<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><style>body {
  max-width: 980px;
  border: 1px solid #ddd;
  outline: 1300px solid #fff;
  margin: 16px auto;
}

body .markdown-body
{
  padding: 45px;
}

@font-face {
  font-family: fontawesome-mini;
  src: url(data:font/woff;charset=utf-8;base64,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) format('woff');
}

.markdown-body {
  font-family: sans-serif;
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
  color: #333333;
  overflow: hidden;
  font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
  font-size: 16px;
  line-height: 1.6;
  word-wrap: break-word;
}

.markdown-body a {
  background: transparent;
}

.markdown-body a:active,
.markdown-body a:hover {
  outline: 0;
}

.markdown-body b,
.markdown-body strong {
  font-weight: bold;
}

.markdown-body mark {
  background: #ff0;
  color: #000;
  font-style: italic;
  font-weight: bold;
}

.markdown-body sub,
.markdown-body sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}
.markdown-body sup {
  top: -0.5em;
}
.markdown-body sub {
  bottom: -0.25em;
}

.markdown-body h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

.markdown-body img {
  border: 0;
}

.markdown-body hr {
  -moz-box-sizing: content-box;
  box-sizing: content-box;
  height: 0;
}

.markdown-body pre {
  overflow: auto;
}

.markdown-body code,
.markdown-body kbd,
.markdown-body pre,
.markdown-body samp {
  font-family: monospace, monospace;
  font-size: 1em;
}

.markdown-body input {
  color: inherit;
  font: inherit;
  margin: 0;
}

.markdown-body html input[disabled] {
  cursor: default;
}

.markdown-body input {
  line-height: normal;
}

.markdown-body input[type="checkbox"] {
  box-sizing: border-box;
  padding: 0;
}

.markdown-body table {
  border-collapse: collapse;
  border-spacing: 0;
}

.markdown-body td,
.markdown-body th {
  padding: 0;
}

.markdown-body .codehilitetable {
  border: 0;
  border-spacing: 0;
}

.markdown-body .codehilitetable tr {
  border: 0;
}

.markdown-body .codehilitetable pre,
.markdown-body .codehilitetable div.codehilite {
  margin: 0;
}

.markdown-body .linenos,
.markdown-body .code,
.markdown-body .codehilitetable td {
  border: 0;
  padding: 0;
}

.markdown-body td:not(.linenos) .linenodiv {
  padding: 0 !important;
}

.markdown-body .code {
  width: 100%;
}

.markdown-body .linenos div pre,
.markdown-body .linenodiv pre,
.markdown-body .linenodiv {
  border: 0;
  -webkit-border-radius: 0;
  -moz-border-radius: 0;
  border-radius: 0;
  -webkit-border-top-left-radius: 3px;
  -webkit-border-bottom-left-radius: 3px;
  -moz-border-radius-topleft: 3px;
  -moz-border-radius-bottomleft: 3px;
  border-top-left-radius: 3px;
  border-bottom-left-radius: 3px;
}

.markdown-body .code div pre,
.markdown-body .code div {
  border: 0;
  -webkit-border-radius: 0;
  -moz-border-radius: 0;
  border-radius: 0;
  -webkit-border-top-right-radius: 3px;
  -webkit-border-bottom-right-radius: 3px;
  -moz-border-radius-topright: 3px;
  -moz-border-radius-bottomright: 3px;
  border-top-right-radius: 3px;
  border-bottom-right-radius: 3px;
}

.markdown-body * {
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

.markdown-body input {
  font: 13px Helvetica, arial, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol";
  line-height: 1.4;
}

.markdown-body a {
  color: #4183c4;
  text-decoration: none;
}

.markdown-body a:hover,
.markdown-body a:focus,
.markdown-body a:active {
  text-decoration: underline;
}

.markdown-body hr {
  height: 0;
  margin: 15px 0;
  overflow: hidden;
  background: transparent;
  border: 0;
  border-bottom: 1px solid #ddd;
}

.markdown-body hr:before,
.markdown-body hr:after {
  display: table;
  content: " ";
}

.markdown-body hr:after {
  clear: both;
}

.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
  margin-top: 15px;
  margin-bottom: 15px;
  line-height: 1.1;
}

.markdown-body h1 {
  font-size: 30px;
}

.markdown-body h2 {
  font-size: 21px;
}

.markdown-body h3 {
  font-size: 16px;
}

.markdown-body h4 {
  font-size: 14px;
}

.markdown-body h5 {
  font-size: 12px;
}

.markdown-body h6 {
  font-size: 11px;
}

.markdown-body blockquote {
  margin: 0;
}

.markdown-body ul,
.markdown-body ol {
  padding: 0;
  margin-top: 0;
  margin-bottom: 0;
}

.markdown-body ol ol,
.markdown-body ul ol {
  list-style-type: lower-roman;
}

.markdown-body ul ul ol,
.markdown-body ul ol ol,
.markdown-body ol ul ol,
.markdown-body ol ol ol {
  list-style-type: lower-alpha;
}

.markdown-body dd {
  margin-left: 0;
}

.markdown-body code,
.markdown-body pre,
.markdown-body samp {
  font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
  font-size: 12px;
}

.markdown-body pre {
  margin-top: 0;
  margin-bottom: 0;
}

.markdown-body kbd {
  background-color: #e7e7e7;
  background-image: -moz-linear-gradient(#fefefe, #e7e7e7);
  background-image: -webkit-linear-gradient(#fefefe, #e7e7e7);
  background-image: linear-gradient(#fefefe, #e7e7e7);
  background-repeat: repeat-x;
  border-radius: 2px;
  border: 1px solid #cfcfcf;
  color: #000;
  padding: 3px 5px;
  line-height: 10px;
  font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
  display: inline-block;
}

.markdown-body>*:first-child {
  margin-top: 0 !important;
}

.markdown-body>*:last-child {
  margin-bottom: 0 !important;
}

.markdown-body .headerlink {
  font: normal 400 16px fontawesome-mini;
  vertical-align: middle;
  margin-left: -16px;
  float: left;
  display: inline-block;
  text-decoration: none;
  opacity: 0;
  color: #333;
}

.markdown-body .headerlink:focus {
  outline: none;
}

.markdown-body h1 .headerlink {
  margin-top: 0.8rem;
}

.markdown-body h2 .headerlink,
.markdown-body h3 .headerlink {
  margin-top: 0.6rem;
}

.markdown-body h4 .headerlink {
  margin-top: 0.2rem;
}

.markdown-body h5 .headerlink,
.markdown-body h6 .headerlink {
  margin-top: 0;
}

.markdown-body .headerlink:hover,
.markdown-body h1:hover .headerlink,
.markdown-body h2:hover .headerlink,
.markdown-body h3:hover .headerlink,
.markdown-body h4:hover .headerlink,
.markdown-body h5:hover .headerlink,
.markdown-body h6:hover .headerlink {
  opacity: 1;
  text-decoration: none;
}

.markdown-body h1 {
  padding-bottom: 0.3em;
  font-size: 2.25em;
  line-height: 1.2;
  border-bottom: 1px solid #eee;
}

.markdown-body h2 {
  padding-bottom: 0.3em;
  font-size: 1.75em;
  line-height: 1.225;
  border-bottom: 1px solid #eee;
}

.markdown-body h3 {
  font-size: 1.5em;
  line-height: 1.43;
}

.markdown-body h4 {
  font-size: 1.25em;
}

.markdown-body h5 {
  font-size: 1em;
}

.markdown-body h6 {
  font-size: 1em;
  color: #777;
}

.markdown-body p,
.markdown-body blockquote,
.markdown-body ul,
.markdown-body ol,
.markdown-body dl,
.markdown-body table,
.markdown-body pre,
.markdown-body .admonition {
  margin-top: 0;
  margin-bottom: 16px;
}

.markdown-body hr {
  height: 4px;
  padding: 0;
  margin: 16px 0;
  background-color: #e7e7e7;
  border: 0 none;
}

.markdown-body ul,
.markdown-body ol {
  padding-left: 2em;
}

.markdown-body ul ul,
.markdown-body ul ol,
.markdown-body ol ol,
.markdown-body ol ul {
  margin-top: 0;
  margin-bottom: 0;
}

.markdown-body li>p {
  margin-top: 16px;
}

.markdown-body dl {
  padding: 0;
}

.markdown-body dl dt {
  padding: 0;
  margin-top: 16px;
  font-size: 1em;
  font-style: italic;
  font-weight: bold;
}

.markdown-body dl dd {
  padding: 0 16px;
  margin-bottom: 16px;
}

.markdown-body blockquote {
  padding: 0 15px;
  color: #777;
  border-left: 4px solid #ddd;
}

.markdown-body blockquote>:first-child {
  margin-top: 0;
}

.markdown-body blockquote>:last-child {
  margin-bottom: 0;
}

.markdown-body table {
  display: block;
  width: 100%;
  overflow: auto;
  word-break: normal;
  word-break: keep-all;
}

.markdown-body table th {
  font-weight: bold;
}

.markdown-body table th,
.markdown-body table td {
  padding: 6px 13px;
  border: 1px solid #ddd;
}

.markdown-body table tr {
  background-color: #fff;
  border-top: 1px solid #ccc;
}

.markdown-body table tr:nth-child(2n) {
  background-color: #f8f8f8;
}

.markdown-body img {
  max-width: 100%;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

.markdown-body code,
.markdown-body samp {
  padding: 0;
  padding-top: 0.2em;
  padding-bottom: 0.2em;
  margin: 0;
  font-size: 85%;
  background-color: rgba(0,0,0,0.04);
  border-radius: 3px;
}

.markdown-body code:before,
.markdown-body code:after {
  letter-spacing: -0.2em;
  content: "\00a0";
}

.markdown-body pre>code {
  padding: 0;
  margin: 0;
  font-size: 100%;
  word-break: normal;
  white-space: pre;
  background: transparent;
  border: 0;
}

.markdown-body .codehilite {
  margin-bottom: 16px;
}

.markdown-body .codehilite pre,
.markdown-body pre {
  padding: 16px;
  overflow: auto;
  font-size: 85%;
  line-height: 1.45;
  background-color: #f7f7f7;
  border-radius: 3px;
}

.markdown-body .codehilite pre {
  margin-bottom: 0;
  word-break: normal;
}

.markdown-body pre {
  word-wrap: normal;
}

.markdown-body pre code {
  display: inline;
  max-width: initial;
  padding: 0;
  margin: 0;
  overflow: initial;
  line-height: inherit;
  word-wrap: normal;
  background-color: transparent;
  border: 0;
}

.markdown-body pre code:before,
.markdown-body pre code:after {
  content: normal;
}

/* Admonition */
.markdown-body .admonition {
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  position: relative;
  border-radius: 3px;
  border: 1px solid #e0e0e0;
  border-left: 6px solid #333;
  padding: 10px 10px 10px 30px;
}

.markdown-body .admonition table {
  color: #333;
}

.markdown-body .admonition p {
  padding: 0;
}

.markdown-body .admonition-title {
  font-weight: bold;
  margin: 0;
}

.markdown-body .admonition>.admonition-title {
  color: #333;
}

.markdown-body .attention>.admonition-title {
  color: #a6d796;
}

.markdown-body .caution>.admonition-title {
  color: #d7a796;
}

.markdown-body .hint>.admonition-title {
  color: #96c6d7;
}

.markdown-body .danger>.admonition-title {
  color: #c25f77;
}

.markdown-body .question>.admonition-title {
  color: #96a6d7;
}

.markdown-body .note>.admonition-title {
  color: #d7c896;
}

.markdown-body .admonition:before,
.markdown-body .attention:before,
.markdown-body .caution:before,
.markdown-body .hint:before,
.markdown-body .danger:before,
.markdown-body .question:before,
.markdown-body .note:before {
  font: normal normal 16px fontawesome-mini;
  -moz-osx-font-smoothing: grayscale;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  line-height: 1.5;
  color: #333;
  position: absolute;
  left: 0;
  top: 0;
  padding-top: 10px;
  padding-left: 10px;
}

.markdown-body .admonition:before {
  content: "\f056\00a0";
  color: 333;
}

.markdown-body .attention:before {
  content: "\f058\00a0";
  color: #a6d796;
}

.markdown-body .caution:before {
  content: "\f06a\00a0";
  color: #d7a796;
}

.markdown-body .hint:before {
  content: "\f05a\00a0";
  color: #96c6d7;
}

.markdown-body .danger:before {
  content: "\f057\00a0";
  color: #c25f77;
}

.markdown-body .question:before {
  content: "\f059\00a0";
  color: #96a6d7;
}

.markdown-body .note:before {
  content: "\f040\00a0";
  color: #d7c896;
}

.markdown-body .admonition::after {
  content: normal;
}

.markdown-body .attention {
  border-left: 6px solid #a6d796;
}

.markdown-body .caution {
  border-left: 6px solid #d7a796;
}

.markdown-body .hint {
  border-left: 6px solid #96c6d7;
}

.markdown-body .danger {
  border-left: 6px solid #c25f77;
}

.markdown-body .question {
  border-left: 6px solid #96a6d7;
}

.markdown-body .note {
  border-left: 6px solid #d7c896;
}

.markdown-body .admonition>*:first-child {
  margin-top: 0 !important;
}

.markdown-body .admonition>*:last-child {
  margin-bottom: 0 !important;
}

/* progress bar*/
.markdown-body .progress {
  display: block;
  width: 300px;
  margin: 10px 0;
  height: 24px;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  border-radius: 3px;
  background-color: #ededed;
  position: relative;
  box-shadow: inset -1px 1px 3px rgba(0, 0, 0, .1);
}

.markdown-body .progress-label {
  position: absolute;
  text-align: center;
  font-weight: bold;
  width: 100%; margin: 0;
  line-height: 24px;
  color: #333;
  text-shadow: 1px 1px 0 #fefefe, -1px -1px 0 #fefefe, -1px 1px 0 #fefefe, 1px -1px 0 #fefefe, 0 1px 0 #fefefe, 0 -1px 0 #fefefe, 1px 0 0 #fefefe, -1px 0 0 #fefefe, 1px 1px 2px #000;
  -webkit-font-smoothing: antialiased !important;
  white-space: nowrap;
  overflow: hidden;
}

.markdown-body .progress-bar {
  height: 24px;
  float: left;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  border-radius: 3px;
  background-color: #96c6d7;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), inset 0 -1px 0 rgba(0, 0, 0, .1);
  background-size: 30px 30px;
  background-image: -webkit-linear-gradient(
    135deg, rgba(255, 255, 255, .4) 27%,
    transparent 27%,
    transparent 52%, rgba(255, 255, 255, .4) 52%,
    rgba(255, 255, 255, .4) 77%,
    transparent 77%, transparent
  );
  background-image: -moz-linear-gradient(
    135deg,
    rgba(255, 255, 255, .4) 27%, transparent 27%,
    transparent 52%, rgba(255, 255, 255, .4) 52%,
    rgba(255, 255, 255, .4) 77%, transparent 77%,
    transparent
  );
  background-image: -ms-linear-gradient(
    135deg,
    rgba(255, 255, 255, .4) 27%, transparent 27%,
    transparent 52%, rgba(255, 255, 255, .4) 52%,
    rgba(255, 255, 255, .4) 77%, transparent 77%,
    transparent
  );
  background-image: -o-linear-gradient(
    135deg,
    rgba(255, 255, 255, .4) 27%, transparent 27%,
    transparent 52%, rgba(255, 255, 255, .4) 52%,
    rgba(255, 255, 255, .4) 77%, transparent 77%,
    transparent
  );
  background-image: linear-gradient(
    135deg,
    rgba(255, 255, 255, .4) 27%, transparent 27%,
    transparent 52%, rgba(255, 255, 255, .4) 52%,
    rgba(255, 255, 255, .4) 77%, transparent 77%,
    transparent
  );
}

.markdown-body .progress-100plus .progress-bar {
  background-color: #a6d796;
}

.markdown-body .progress-80plus .progress-bar {
  background-color: #c6d796;
}

.markdown-body .progress-60plus .progress-bar {
  background-color: #d7c896;
}

.markdown-body .progress-40plus .progress-bar {
  background-color: #d7a796;
}

.markdown-body .progress-20plus .progress-bar {
  background-color: #d796a6;
}

.markdown-body .progress-0plus .progress-bar {
  background-color: #c25f77;
}

.markdown-body .candystripe-animate .progress-bar{
  -webkit-animation: animate-stripes 3s linear infinite;
  -moz-animation: animate-stripes 3s linear infinite;
  animation: animate-stripes 3s linear infinite;
}

@-webkit-keyframes animate-stripes {
  0% {
    background-position: 0 0;
  }

  100% {
    background-position: 60px 0;
  }
}

@-moz-keyframes animate-stripes {
  0% {
    background-position: 0 0;
  }

  100% {
    background-position: 60px 0;
  }
}

@keyframes animate-stripes {
  0% {
    background-position: 0 0;
  }

  100% {
    background-position: 60px 0;
  }
}

.markdown-body .gloss .progress-bar {
  box-shadow:
    inset 0 4px 12px rgba(255, 255, 255, .7),
    inset 0 -12px 0 rgba(0, 0, 0, .05);
}

/* Multimarkdown Critic Blocks */
.markdown-body .critic_mark {
  background: #ff0;
}

.markdown-body .critic_delete {
  color: #c82829;
  text-decoration: line-through;
}

.markdown-body .critic_insert {
  color: #718c00 ;
  text-decoration: underline;
}

.markdown-body .critic_comment {
  color: #8e908c;
  font-style: italic;
}

.markdown-body .headeranchor {
  font: normal normal 16px fontawesome-mini;
  line-height: 1;
  display: inline-block;
  text-decoration: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.headeranchor:before {
  content: '\e157';
}

.markdown-body .task-list-item {
  list-style-type: none;
}

.markdown-body .task-list-item+.task-list-item {
  margin-top: 3px;
}

.markdown-body .task-list-item input {
  margin: 0 4px 0.25em -20px;
  vertical-align: middle;
}

/* Media */
@media only screen and (min-width: 480px) {
  .markdown-body {
    font-size:14px;
  }
}

@media only screen and (min-width: 768px) {
  .markdown-body {
    font-size:16px;
  }
}

@media print {
  .markdown-body * {
    background: transparent !important;
    color: black !important;
    filter:none !important;
    -ms-filter: none !important;
  }

  .markdown-body {
    font-size:12pt;
    max-width:100%;
    outline:none;
    border: 0;
  }

  .markdown-body a,
  .markdown-body a:visited {
    text-decoration: underline;
  }

  .markdown-body .headeranchor-link {
    display: none;
  }

  .markdown-body a[href]:after {
    content: " (" attr(href) ")";
  }

  .markdown-body abbr[title]:after {
    content: " (" attr(title) ")";
  }

  .markdown-body .ir a:after,
  .markdown-body a[href^="javascript:"]:after,
  .markdown-body a[href^="#"]:after {
    content: "";
  }

  .markdown-body pre {
    white-space: pre;
    white-space: pre-wrap;
    word-wrap: break-word;
  }

  .markdown-body pre,
  .markdown-body blockquote {
    border: 1px solid #999;
    padding-right: 1em;
    page-break-inside: avoid;
  }

  .markdown-body .progress,
  .markdown-body .progress-bar {
    -moz-box-shadow: none;
    -webkit-box-shadow: none;
    box-shadow: none;
  }

  .markdown-body .progress {
    border: 1px solid #ddd;
  }

  .markdown-body .progress-bar {
    height: 22px;
    border-right: 1px solid #ddd;
  }

  .markdown-body tr,
  .markdown-body img {
    page-break-inside: avoid;
  }

  .markdown-body img {
    max-width: 100% !important;
  }

  .markdown-body p,
  .markdown-body h2,
  .markdown-body h3 {
    orphans: 3;
    widows: 3;
  }

  .markdown-body h2,
  .markdown-body h3 {
    page-break-after: avoid;
  }
}
</style><style>/*github*/
.codehilite {background-color:#fff;color:#333333;}
.codehilite .hll {background-color:#ffffcc;}
.codehilite .c{color:#999988;font-style:italic}
.codehilite .err{color:#a61717;background-color:#e3d2d2}
.codehilite .k{font-weight:bold}
.codehilite .o{font-weight:bold}
.codehilite .cm{color:#999988;font-style:italic}
.codehilite .cp{color:#999999;font-weight:bold}
.codehilite .c1{color:#999988;font-style:italic}
.codehilite .cs{color:#999999;font-weight:bold;font-style:italic}
.codehilite .gd{color:#000000;background-color:#ffdddd}
.codehilite .ge{font-style:italic}
.codehilite .gr{color:#aa0000}
.codehilite .gh{color:#999999}
.codehilite .gi{color:#000000;background-color:#ddffdd}
.codehilite .go{color:#888888}
.codehilite .gp{color:#555555}
.codehilite .gs{font-weight:bold}
.codehilite .gu{color:#800080;font-weight:bold}
.codehilite .gt{color:#aa0000}
.codehilite .kc{font-weight:bold}
.codehilite .kd{font-weight:bold}
.codehilite .kn{font-weight:bold}
.codehilite .kp{font-weight:bold}
.codehilite .kr{font-weight:bold}
.codehilite .kt{color:#445588;font-weight:bold}
.codehilite .m{color:#009999}
.codehilite .s{color:#dd1144}
.codehilite .n{color:#333333}
.codehilite .na{color:teal}
.codehilite .nb{color:#0086b3}
.codehilite .nc{color:#445588;font-weight:bold}
.codehilite .no{color:teal}
.codehilite .ni{color:purple}
.codehilite .ne{color:#990000;font-weight:bold}
.codehilite .nf{color:#990000;font-weight:bold}
.codehilite .nn{color:#555555}
.codehilite .nt{color:navy}
.codehilite .nv{color:teal}
.codehilite .ow{font-weight:bold}
.codehilite .w{color:#bbbbbb}
.codehilite .mf{color:#009999}
.codehilite .mh{color:#009999}
.codehilite .mi{color:#009999}
.codehilite .mo{color:#009999}
.codehilite .sb{color:#dd1144}
.codehilite .sc{color:#dd1144}
.codehilite .sd{color:#dd1144}
.codehilite .s2{color:#dd1144}
.codehilite .se{color:#dd1144}
.codehilite .sh{color:#dd1144}
.codehilite .si{color:#dd1144}
.codehilite .sx{color:#dd1144}
.codehilite .sr{color:#009926}
.codehilite .s1{color:#dd1144}
.codehilite .ss{color:#990073}
.codehilite .bp{color:#999999}
.codehilite .vc{color:teal}
.codehilite .vg{color:teal}
.codehilite .vi{color:teal}
.codehilite .il{color:#009999}
.codehilite .gc{color:#999;background-color:#EAF2F5}
</style><title>机器学习学习文档</title></head><body><article class="markdown-body"><h2 id="_1">什么是机器学习<a class="headerlink" href="#_1" title="Permanent link"></a></h2>
<ul>
<li>机器学习是从<strong>数据</strong>中自动分析获得<strong>规律(模型)</strong>，并利用规律对<strong>未知数据进行预测</strong>*</li>
</ul>
<h2 id="_2">机器学习组成<a class="headerlink" href="#_2" title="Permanent link"></a></h2>
<p>Learning= Representation+Evalution+Optimization
模型：将实际问题转化成为计算机可以理解的问题，就是我们平时说的建模。（数据+算法）
评测：评测的目标是判断已建好的模型的优劣(api都在metrics内，包括精确率召回率，各种算法的评价标准)
优化：寻找更好的模型，得到更好的评测结果</p>
<h2 id="_3">机器学习的应用场景<a class="headerlink" href="#_3" title="Permanent link"></a></h2>
<ul>
<li>广告搜索</li>
<li>广告推荐，根据历史行为及历史购买商品</li>
<li>阿尔法狗</li>
</ul>
<h2 id="_4">为什么需要机器学习<a class="headerlink" href="#_4" title="Permanent link"></a></h2>
<ul>
<li>未来人口减少，肯定需要机器代替很多人的工作才可以</li>
<li>只能客服（解放生产力）</li>
<li>解决专业问题（ET医疗）</li>
<li>提供社会便利（城市大脑）</li>
</ul>
<h2 id="_5">机器学习的目的<a class="headerlink" href="#_5" title="Permanent link"></a></h2>
<ul>
<li><strong>让机器学习程序替换手动的步骤，减少企业的成本也提高企业的效率</strong>*</li>
<li>自动客户分类，推送不同的广告（自然带来价值）</li>
</ul>
<h2 id="_6">竞赛<a class="headerlink" href="#_6" title="Permanent link"></a></h2>
<p><a href="https://tianchi.aliyun.com/">天池大赛</a>
<a href="https://www.kaggle.com/">kaggle</a> 下载数据需要注册帐号，激活时注意需要fq才能看到验证码
<a href="https://jdata.jd.com/html/list.html">京东</a>
<a href="http://www.studyai.com/course/index/">机器学习网站</a>
<a href="http://www.sogou.com/labs/resource/list_pingce.php">搜狗实验室</a>，可获取数据除了</p>
<h2 id="_7">数据集的组成<a class="headerlink" href="#_7" title="Permanent link"></a></h2>
<h3 id="_8">机器学习的数据存储<a class="headerlink" href="#_8" title="Permanent link"></a></h3>
<ul>
<li>很多情况下存储在csv文件</li>
<li>常规数据库的问题<ul>
<li>mysql、mongodb
    1、性能瓶颈，读取速度限制
    2、格式不太符合机器学习要求数据的格式</li>
</ul>
</li>
</ul>
<h3 id="_9">数据读取<a class="headerlink" href="#_9" title="Permanent link"></a></h3>
<ul>
<li>pandas：读取工具，依托于numpy</li>
<li>numpy是由c开发的，解决了GIL的问题，多线程都是真正的多线程</li>
</ul>
<h3 id="_10">可用数据集<a class="headerlink" href="#_10" title="Permanent link"></a></h3>
<ul>
<li>kaggle：大数据竞赛平台、真实数据、数据巨大  <a href="https://www.kaggle.com/datasets">https://www.kaggle.com/datasets</a></li>
<li>UCI：专业数据，收录360个数据集、覆盖科学生活经济、数据量几十万    <a href="http://archive.ics.uci.edu/ml/">http://archive.ics.uci.edu/ml/</a></li>
<li>sklearn：数据量小，方便学习 <a href="http://scikit-learn.org/stable/datasets/index.html#datasets">http://scikit-learn.org/stable/datasets/index.html#datasets</a></li>
</ul>
<h3 id="_11"><strong>常用数据集组成</strong><a class="headerlink" href="#_11" title="Permanent link"></a></h3>
<ul>
<li>结构：特征值+目标值</li>
<li>目标值，即想要获得的结果，如判断一个人是男是女</li>
<li>特征值，描述一个物体所需要的条件，如房子大小，户型，朝向等</li>
<li>每条数据集就是一个样本</li>
</ul>
<h2 id="_12">特征工程（重要）<a class="headerlink" href="#_12" title="Permanent link"></a></h2>
<h3 id="_13">数据中对于特征的处理：<a class="headerlink" href="#_13" title="Permanent link"></a></h3>
<ul>
<li>pandas：一个数据读取非常方便以及基本的处理格式的工具（缺失值处理，重复值无需处理）</li>
<li>sklearn：对于<strong>特征</strong>的处理提供了强大的接口(如文字计算机是无法处理的，需要将每个文字也就是特征转化为数字)</li>
</ul>
<h3 id="_14">特征工程是什么<a class="headerlink" href="#_14" title="Permanent link"></a></h3>
<ul>
<li>
<p>特征工程是将原始数据转换为更好地代表预测模型的潜在问题的特征的过程，从而提高对未知数据的预测准确性</p>
</li>
<li>
<p>特征抽取</p>
</li>
<li>特征抽取对文本等数据进行特征值化</li>
<li>
<p>特征值化是为了计算机更好的去理解数据</p>
</li>
<li>
<p>特征预处理</p>
</li>
<li>数据降维（特征选择）</li>
</ul>
<p>以上为常见的特征工程的三种处理方式
特征抽取针对类别型数据，如字典，文本；特征预处理针对数值型数据；数据降维，特征选择用于去除无效特征</p>
<h3 id="_15">特征抽取<a class="headerlink" href="#_15" title="Permanent link"></a></h3>
<p>类别型数据：one-hot编码</p>
<h3 id="one-hot">字典特征数据的抽取（one-hot编码）<a class="headerlink" href="#one-hot" title="Permanent link"></a></h3>
<ul>
<li>api：sklearn.feature_extraction.DictVectorizer(字典矢量化)</li>
<li>默认是sparse矩阵，目的是节约内存，方便读取处理，如果使用了稀疏矩阵，想要将结果转为普通数组，在稀疏矩阵上使用toarray()方法即可</li>
<li>字典数据数据：把字典中的一些类别数据，分别进行转换成特征，如key：value转为key=value为一个特征，形成one-hot编码。数值类型不会进行转化，而是将数值类型的对应的key作为一个特征存在。</li>
<li>DictVectorizer.fit_transform(X)     <br />
    X:字典或者包含字典的迭代器，得到的是除数字外均为one-hot编码的形式</li>
<li>DictVectorizer.inverse_transform(X)  将抽取的特征转换成原本的样子
    X:ndarray数组或者sparse矩阵</li>
<li>DictVectorizer.get_feature_names()
    返回类别名称</li>
</ul>
<h3 id="_16">文本特征抽取（词频统计）<a class="headerlink" href="#_16" title="Permanent link"></a></h3>
<p>CountVectorizer和TfidfVectorizer，前者只有词频，后者有区分词汇的重要性</p>
<h4 id="_17">停用词<a class="headerlink" href="#_17" title="Permanent link"></a></h4>
<p>1.语料中大量出现（如一些，一样，等等）
2.没啥大用</p>
<h4 id="_18">相似度<a class="headerlink" href="#_18" title="Permanent link"></a></h4>
<p>针对的是句子或者文字的相似度对比
句子A：我喜欢看电视，不喜欢看电影。
句子B：我不喜欢看电视，也不喜欢看电影。
分词：
句子A：我/喜欢/看/电视，不/喜欢/看/电影。
句子B：我/不/喜欢/看/电视，也/不/喜欢/看/电影。
语料库：我，喜欢，看，电视，电影，不，也。
词频：
句子A：我 1，喜欢 2，看 2，电视 1，电影 1，不 1，也 0。
句子B：我 1，喜欢 2，看 2，电视 1，电影 1，不 2，也 1。
词频向量：
句子A：[1, 2, 2, 1, 1, 1, 0]
句子B：[1, 2, 2, 1, 1, 2, 1]</p>
<p>以上也是文本特征抽取的过程</p>
<p>常用的相似度分析方法采用余弦值，即两个向量之间的夹角来判断是否相似
因向量相等表明大小相等，方向相同，两者接近，夹角越小，当夹角为0，cos值为1，此时两者完全相同，以此来判断两个文本的相似度
<img alt="相似度计算" src="https://img-blog.csdnimg.cn/20181126102533612.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hZRVND,size_16,color_FFFFFF,t_70" /></p>
<h4 id="_19">英文文本特征抽取<a class="headerlink" href="#_19" title="Permanent link"></a></h4>
<ul>
<li>api：sklearn.feature_extraction.text.CountVectorizer  (返回结果是统计每个词的词频)</li>
<li>所有文章保存在一个列表中</li>
<li>统计所有文章中所有的词汇，去重，放在列表中，是 <code>get_feature_names()</code> 得到的列表</li>
<li>对每篇文章，在词的列表里面进行统计每个词出现的次数，单个字母不统计，得到二维数组</li>
<li>对于单个英文字母没有统计的意义</li>
<li>是以空格来进行分割词汇的，因此中文也需要在分词后以空格进行拼接</li>
</ul>
<h4 id="_20">中文文本特征抽取<a class="headerlink" href="#_20" title="Permanent link"></a></h4>
<ul>
<li>分词</li>
<li>将分词后的列表以空格间隔拼接为完成的文章</li>
<li>将文章放入列表中，之后的方式和英文处理方式雷同</li>
</ul>
<h3 id="tf-idf">tf-idf分析问题<a class="headerlink" href="#tf-idf" title="Permanent link"></a></h3>
<ul>
<li>词频：各文档中每个单词的出现次数除以该文档中所有单词的总数</li>
<li>
<p>上述文本特征抽取，仅仅是得到了词频，即词汇在文章中出现的次数
问题描述：将很多文章进行统计分类时，每篇文章都可能出现很多语气词，我们，因为所以等词汇，不能因为每个文章都出现了很多此类词汇而将文章划归为一类，因此需要过滤掉这些词汇，此时就需要tf-idf（词频-逆文档频率）了</p>
</li>
<li>
<p>tf：term frequency 词频   idf  inverse document frequency
idf = log(总文章数量/该词出现的文章数量)，越大说明该词出现的文章较少，那么该词在出现的文章中就较为重要，如果和词频相乘，就得到了该词在这篇文章中的重要程度</p>
</li>
<li>最终结果是有 <code>tf*idf</code> 得到的结果（词汇在该文章出现的次数 * idf）</li>
<li>
<p>主要思想：如果某个词或短语在一篇文章中出现的概率高，同时在其他文章中很少出现，则认为这个词具有很好的类别区分能力，适合用来分类，即idf值大</p>
</li>
<li>
<p>注意：sklearn实现的tfidf与百科搜索的计算公式不太相同，区别点如下：
1、标准计算是log 以10为底的对数，sklearn则是以e为底的计算
2、tf词频，标准计算是某个词在某个文章中出现的次数除以此文章的总词数，但是sklearn使用的就是某个词出现的次数，如this这个词出现了5次，就用5参与计算
3、创建对象时的norm和smooth_idf分别表示归一化和平滑计算，详细见 <a href="http://sklearn.apachecn.org/cn/0.19.0/modules/feature_extraction.html">官方文档</a>
4、结论，使用默认值即可</p>
</li>
</ul>
<p>上述CountVectorizer和tfidf两个api的常用参数还有：
<div class="codehilite"><pre>analyzer  # {‘word’, ‘char’, ‘char_wb’} word表示以单词进行分；该功能是否应由word或character  n-gram组成。选项&#39;char_wb&#39;仅从字边界内的文本创建character n-gram;单词边缘的n-gram用空格填充。
max_features  # 如果不是None，则构建一个词汇表，该词汇表仅考虑语料库中按术语频率排序的最高max_features。
lowercase  # 在标记化之前将所有字符转换为小写。
stop_words  # 如果是“english”，则使用英语的内置停用词列表。如果是列表，该列表被假定包含停用词，则所有这些将从生成的tokens中删除。仅适用于analyzer ==&#39;word&#39;。
ngram_range  # 要提取的不同n-gram的n值范围的下边界和上边界。将使用n的所有值，使得min_n &lt;= n &lt;= max_n。一般取(1,2)即可，意思是取出的特征可以是一个单词，也可以是两个单词组成的词汇
</pre></div></p>
<h3 id="gensim">gensim<a class="headerlink" href="#gensim" title="Permanent link"></a></h3>
<p>可以</p>
<h3 id="_21">特征预处理 数值型数据归一化标准化<a class="headerlink" href="#_21" title="Permanent link"></a></h3>
<p>sklearn.preprocessing
+ 针对的数值型的数据
定义：通过特定的统计方法（数学方法）将数据转换成<strong>算法要求</strong>的数据
+ 标准缩放
- 归一化
- 标准化
- 缺失值</p>
<h4 id="_22">归一化，针对数值型<a class="headerlink" href="#_22" title="Permanent link"></a></h4>
<p>特点：通过对原始数据进行变换把数据映射到默认为[0,1]之间
<code>X1 = (x - min) / (max - min)</code>
<code>X2 = X1 *(mx - mi) + mi</code>
以上公式中mi为区间最小值，默认为0，mx为区间最大值，默认为1，因此默认情况下X1=X2</p>
<p>归一化的原因：利用某个算法进行计算时，如果样本的每个特征同等重要，但是每个特征的数值差异非常大，利用此算法计算后，就会导致每个特征的重要性不同，与预期相悖。此时就需要对
目的：使得某个特征对最终结果不会造成过大的影响
缺点：被异常点影响结果，鲁棒性较差，只适合传统精确小数据场景，使用的情况很少</p>
<h4 id="_23">标准化，针对数值型<a class="headerlink" href="#_23" title="Permanent link"></a></h4>
<p>标准化的生成的对象，使用fit_transform时，需要传递的是二维数组，不能是一维，会报错，这是由于需要计算标准差，平均值等内容，只有二维方便按列进行计算
特点：通过对原始数据进行变换，把数据变换到均值为0，标准差为1的标准正态分布（高斯分布）
公式1：X1 = (x - mean) / 标准差<br />
原标准差 = sqart((x1 - mean)^2 + &hellip; + (xn - mean)^2 / n)
方差考量数据的稳定性</p>
<p>均值为0 ：原因  由公式1推出，每个计算得到的值相加，分母为标准差，分子为 <code>x1+x2+...+xn - mean*n = 0</code> 整好等于0，和为0，均值自然为0
新的标准差为1：原因：均值为0，求标准差时，每个值是上边求出的X1，将X1代入标准差计算公式，求解后会得出 原标准差/原标准差的结果，得1。过程见图：
<img alt="标准差为1，均值为0" src="https://img-blog.csdnimg.cn/20181108134212534.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hZRVND,size_16,color_FFFFFF,t_70" /></p>
<p>优点：通过平均值来计算缩放后的值，平均值中和了异常点，使异常点对结果的影响减少到忽略不计
应用场景：在已有样本足够多的情况下比较稳定，适合现代嘈杂大数据场景</p>
<h2 id="simpleimputer">缺失值处理SimpleImputer<a class="headerlink" href="#simpleimputer" title="Permanent link"></a></h2>
<ul>
<li>一般会在pandas中对缺失值处理，sklearn也提供了缺失值处理api</li>
<li>可以通过缺失值每行或者每列的平均值、中位数来填充，建议按列填补（对应每个特征）</li>
<li>sklearn缺失值API:  sklearn.preprocessing.Imputer
注意：在0.20版中，Imputer的位置改变，使用sklearn.imputer.SimpleImputer 功能一致</li>
<li>Imputer(missing_values=&rsquo;NaN&rsquo;, strategy=&rsquo;mean&rsquo;, axis=0)  完成缺失值插补
缺失值的格式默认是np.nan ，使用中针对列表中的 <code>'nan','NaN',None</code> 均可进行替换</li>
</ul>
<h2 id="_24">特征选择<a class="headerlink" href="#_24" title="Permanent link"></a></h2>
<p>过滤式：低方差特征
嵌⼊入式：正则化，决策树（对特征重要性进行了选择），神经⽹络</p>
<p>其中过滤式的特征选择后，数据本身不变，而数据的维度减少（删除低方差特征）。而嵌入式的特征选择方法也会改变数据的值，维度也改变。Embedded（嵌入式）方式是一种自动学习的特征选择方法，后面讲到具体的方法的时候就能理解了。</p>
<h3 id="_25">特征选择原因<a class="headerlink" href="#_25" title="Permanent link"></a></h3>
<ul>
<li>冗余：部分特征的相关度高，容易消耗计算性能</li>
<li>相关度高意思是比如两组数据之间有比例关系，那么这两组数据实际上一组就可以代表了</li>
<li>噪声：部分特征对预测结果有负影响</li>
</ul>
<p>特征选择主要有两个功能：
（1）减少特征数量，降维，使模型泛化能力更强，减少过拟合
（2）增强特征和特征值之间的理解（？是否笔误）</p>
<h3 id="_26">过滤式降维<a class="headerlink" href="#_26" title="Permanent link"></a></h3>
<ul>
<li>Filter(过滤式):VarianceThreshold（方差阈值）  variance方差，通过方差进行过滤，方差为0或者过小，表示一列数据都一样或相近，判定这个特征没有意义，这列数据可以排除</li>
<li>sklearn.feature_selection.VarianceThreshold</li>
<li>VarianceThreshold(threshold = 0.0)  删除所有低方差特征，threshold阈值，也是要过滤的方差值大小，一般小于10，没有固定的，根据实际需求设置</li>
<li>Variance.fit_transform(X)     <br />
X:numpy array格式的数据[n_samples,n_features]
返回值：训练集差异低于threshold的特征将被删除。默认值是保留所有非零方差特征，即删除所有样本中具有相同值的特征。</li>
<li>结果：特征数量会减少，保留下的特征数据不会更改（和pca的重要区别）</li>
</ul>
<h3 id="pca">PCA 主成分分析<a class="headerlink" href="#pca" title="Permanent link"></a></h3>
<p><a href="https://www.cnblogs.com/zy230530/p/7074215.html">pca解释</a>
sklearn的pca解释看不懂
+ 特点是保存数据集中对<strong>方差影响最大</strong>的那些特征，PCA极其容易受到数据中特征范围影响，所以在运用PCA前一定要做<strong>特征标准化</strong>，这样才能保证每维度特征的重要性等同。</p>
<p>降维本质上是从一个维度空间映射到另一个维度空间，特征的多少并没有减少，当然在映射的过程中特征值也会相应的变化。举个例子，现在的特征是1000维，我们想要把它降到500维。降维的过程就是找个一个从1000维映射到500维的映射关系。原始数据中的1000个特征，每一个都对应着降维后的500维空间中的一个值。假设原始特征中有个特征的值是9，那么降维后对应的值可能是3。
理解：如使用二维图来表示三维物体。再比如x，y两轴上的点降维到一个轴上，即画一个斜线，x，y轴的点做垂线到此斜线</p>
<ul>
<li>针对特征数量较多，一般超过一百个以上</li>
<li>
<p>sklearn. decomposition</p>
</li>
<li>
<p>本质：PCA是一种分析、简化数据集的技术</p>
</li>
<li>
<p>目的：是数据维数压缩，尽可能降低原数据的维数（复杂度），损失少量信息。</p>
</li>
<li>
<p>作用：可以削减回归分析或者聚类分析中特征的数量</p>
</li>
</ul>
<p>高维度（特征数量庞大）数据容易出现的问题：特征之间通常是线性相关的</p>
<p>PCA(n_components=None)
将数据分解为较低维数空间
PCA.fit_transform(X)     <br />
X:numpy array格式的数据[n_samples,n_features]
返回值：转换后指定维度的array</p>
<p>n_componets  <br />
小数形式：0.9-0.95取值 最佳    可以理解为特征丢失率在0.05-0.1  <br />
整数形式：要降到多少个特征，一般无法确定，因此不用
+ PCA案例的关键点在于pd关于表的合并上</p>
<h3 id="_27">总结<a class="headerlink" href="#_27" title="Permanent link"></a></h3>
<p>数值型数据：
特征预处理，标准缩放：
    归一化
    标准化
类别型数据：one-hot编码   （字典数据，文本数据，特征抽取）
时间类型：时间的切分
数据降维：特征选择，PCA主成分分析</p>
<h2 id="sklearn">sklearn数据集<a class="headerlink" href="#sklearn" title="Permanent link"></a></h2>
<p>+</p>
<h2 id="_28">机器学习算法分类及开发流程<a class="headerlink" href="#_28" title="Permanent link"></a></h2>
<ul>
<li>算法是核心，数据和计算是基础</li>
<li>机器学习模型是通过一种映射关系将输入值到输出值，这个映射关系就是模型</li>
<li>模型包含：算法+数据，不仅仅只是算法，还要有数据来训练以做出模型</li>
</ul>
<h3 id="_29">如何选择算法<a class="headerlink" href="#_29" title="Permanent link"></a></h3>
<p>在解决问题的时候，必须考虑下面两个问题：
一、使用机器学习算法的目的，想要算法完成何种任务，比如是预测明天下雨的概率是对投票者按照兴趣分组；
二、需要分析或者收集的数据是什么</p>
<h3 id="_30">算法分类<a class="headerlink" href="#_30" title="Permanent link"></a></h3>
<h4 id="_31">监督学习<a class="headerlink" href="#_31" title="Permanent link"></a></h4>
<ul>
<li>简单理解，就是有目标值</li>
<li>可以由输入数据中学到或建立一个模型，并依此模式推测新的结果。输入数据是由输入特征值和目标值所组成。函数的输出可以是一个连续的值
（称为回归），或是输出是有限个离散值（称作分类）。</li>
<li>
<p>离散值，可认为是整数，不可分割，如分类问题，总是有个明确的类别，可用单个数字表示；连续型数据可认为是浮点数，可无限分割，如股票价格等</p>
</li>
<li>
<p>分类</p>
</li>
<li>分类是监督学习的一个核心问题，在监督学习中，当输出变量取有限个离散值时，预测问题变成为分类问题。最基础的便是二分类问题，即判断是非，从两个类别中选择一个作为预测结果</li>
<li>
<p>k-近邻、朴素贝叶斯、决策树与随机森林、逻辑回归、神经网络</p>
</li>
<li>
<p>回归</p>
</li>
<li>回归是监督学习的另一个重要问题。回归用于预测输入变量和输出变量之间的关系，输出是连续型的值。</li>
<li>线性回归，岭回归</li>
<li>标注</li>
<li>隐马尔可夫模型</li>
</ul>
<h4 id="_32">非监督学习<a class="headerlink" href="#_32" title="Permanent link"></a></h4>
<ul>
<li>没有目标值</li>
<li>
<p>可以由输入数据中学到或建立一个模型，并依此模式推测新的结果。输入数据是由输入特征值所组成。</p>
</li>
<li>
<p>聚类：k-means</p>
</li>
</ul>
<h3 id="_33">流程<a class="headerlink" href="#_33" title="Permanent link"></a></h3>
<p>1、建立模型，根据数据类型划分应用种类，明确要解决什么问题
2、数据的基本处理，如缺失值处理，表合并
    - 可以通过绘图的方式将其可视化，常用绘制散点图，对于超过两个特征的数据，可以两两构成特征绘图，这种方式成为散点图矩阵，此图无法同时显示所有特征之间的关系
3、特征工程（重要），如抽取，降维，预处理
4、找到合适的算法，得到模型
5、对模型进行评估，判断效果
6、效果不佳的处理方式：1、更换算法  2、重新处理特征工程</p>
<h1 id="02">机器学习02<a class="headerlink" href="#02" title="Permanent link"></a></h1>
<h2 id="_34">数据集<a class="headerlink" href="#_34" title="Permanent link"></a></h2>
<h3 id="_35">数据集划分<a class="headerlink" href="#_35" title="Permanent link"></a></h3>
<ul>
<li>机器学习一般的数据集会划分为两个部分：</li>
<li>训练数据：用于训练，构建模型（训练集）</li>
<li>测试数据：在模型检验时使用，用于评估模型是否有效（测试集）</li>
</ul>
<h3 id="sklearnapi">sklearn数据集划分API<a class="headerlink" href="#sklearnapi" title="Permanent link"></a></h3>
<p>sklearn.model_selection.train_test_split</p>
<h3 id="scikit-learn">scikit-learn数据集<a class="headerlink" href="#scikit-learn" title="Permanent link"></a></h3>
<p>sklearn.datasets
+ 小数据集
    加载获取流行数据集datasets.load_<em>()
    获取小规模数据集，数据包含在datasets里，安装sklearn后已经安装
+ 大数据集
    datasets.fetch_</em>(data_home=None)
    获取大规模数据集，需要从网络上下载，函数的第一个参数是data_home，表示数据集下载的目录,默认是 <code>~/scikit_learn_data/</code>
    windows存储路径<code>C:\Users\HY\scikit_learn_data\</code>
+ 获取数据集返回的类型
    load<em>和fetch</em>返回的数据类型datasets.base.Bunch(字典格式)</p>
<div class="codehilite"><pre>data：特征数据数组，是 [n_samples * n_features] 的二维numpy.ndarray 数组（特征值）

target：标签数组，是 n_samples 的一维 numpy.ndarray 数组（目标值）

DESCR：数据描述

feature_names：特征名,新闻数据，手写数字、回归数据集没有

target_names：标签名,回归数据集没有
以上可以通过点或字典的取值方式，获取结果
Bunch继承自dict
</pre></div>


<h3 id="_36">数据集进行分割<a class="headerlink" href="#_36" title="Permanent link"></a></h3>
<p><code>sklearn.model_selection.train_test_split(*arrays, **options)</code>  新版</p>
<ul>
<li>
<p>参数
    x          数据集的特征值
    y          数据集的目标值
    test_size      测试集的大小，一般为float
    random_state       随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
return  训练集特征值，测试集特征值，训练目标值，测试目标值(默认随机取)，即以特征值和目标值划分结果</p>
</li>
<li>
<p>划分
一般情况下，训练集：测试集 = 0.75:0.25</p>
</li>
</ul>
<h3 id="_37">用于分类的大数据集<a class="headerlink" href="#_37" title="Permanent link"></a></h3>
<p><code>sklearn.datasets.fetch_20newsgroups(data_home=None,subset=‘train’)</code></p>
<p>subset: &lsquo;train&rsquo;或者&rsquo;test&rsquo;,&rsquo;all&rsquo;，可选，选择要加载的数据集.训练集的“训练”，测试集的“测试”，两者的“全部”
一般选all，自行划分
<code>datasets.clear_data_home(data_home=None)</code>清除目录下的数据</p>
<h2 id="_38">转换器和估计器<a class="headerlink" href="#_38" title="Permanent link"></a></h2>
<h3 id="api">转换器（特征工程api）<a class="headerlink" href="#api" title="Permanent link"></a></h3>
<ul>
<li>是实现了一类特征工程的api</li>
<li>在转换器中，一般直接使用fit_transform，不分别是用fit和transform<ul>
<li>fit 一般是在计算一些数据，如特征预处理时需要的标准差，平均值等</li>
<li>transform是通过fit计算得到的数据来将原始数据转换为想要的数据</li>
<li>估计器中的fit和transform做的事情和上述类似</li>
</ul>
</li>
</ul>
<h3 id="api_1">估计器（算法api）<a class="headerlink" href="#api_1" title="Permanent link"></a></h3>
<ul>
<li>在sklearn中，估计器(estimator)是一个重要的角色，分类器和回归器都属于estimator，是一类实现了<strong>算法</strong>的API
transform用学习到的参数转换数据（尚未使用过，不是很明白什么意思？？）</li>
<li>每个算法api的使用流程
1、调用fit(x_train, y_train)  fit方法用于从训练集中学习模型参数
2、估计器 
    y_predict = predict(x_test)  通过测试集的特征值，计算预测值
    score = score(x_test, y_test)  预测精度
3、输入与测试集的数据</li>
</ul>
<h1 id="_39">算法<a class="headerlink" href="#_39" title="Permanent link"></a></h1>
<ul>
<li>分类算法的依据：目标值是离散型数据</li>
</ul>
<h2 id="kknn">k近邻（KNN算法，实践应用不多）<a class="headerlink" href="#kknn" title="Permanent link"></a></h2>
<p>knn：k-NearestNeighbor，k最近邻
+ 定义：如果一个样本在特征空间中的<strong>k个</strong>最相似(即特征空间中最邻近的样本中的<strong>大多数</strong>属于某一个类别，则该样本也属于这个类别。
+ 计算距离公式
欧式公式：根号((a1-b1)^2+(a2-b2)^2+&hellip;+ (an-bn)^2)
+ 解释：此公式计算的是两个样本之间的距离，即要预测某个测试样本的目标值，需要将此样本与特征集中的每个样本进行差值平方计算，并且是每个样本的每个特征均需要计算
+ 从以上解释可发现，每个特征均需要平方计算，如果每个特征的数据大小差异过大，就会造成特征的重要性不同，对结果造成影响，因此需要进行<strong>标准化处理</strong>，也就是k近邻算法需要进行特征预处理；同时可发现预测一个样本的结果，就需要和特征中的每个样本都进行平方计算，同时还要找出k个最相近的结果中大部分的类别，时间复杂度肯定是高的</p>
<p>KNN算法不仅可以用于分类，还可以用于回归。通过找出一个样本的k个最近邻居，将这些邻居的属性的平均值赋给该样本，就可以得到该样本的属性。更有用的方法是将不同距离的邻居对该样本产生的影响给予不同的权值(weight)，如权值与距离成反比。</p>
<h3 id="knn-api">knn-api<a class="headerlink" href="#knn-api" title="Permanent link"></a></h3>
<p><code>sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto',n_jobs=1)</code>
主要参数介绍：
- n_neighbors：int,可选（默认= 5），k_neighbors查询默认使用的邻居数<br />
    algorithm：{‘auto’，‘ball_tree’，‘kd_tree’，‘brute’}，可选用于计算最近邻居的算法：‘ball_tree’将会使用 BallTree，‘kd_tree’将使用 KDTree。‘auto’将尝试根据传递给fit方法的值来决定最合适的算法。 (不同实现方式影响效率)，一般默认
- n_jobs：int，可选（默认= 1),用于邻居搜索的并行作业数。如果-1，则将作业数设置为CPU内核数。不影响fit方法。应该是用来加快计算速度的。</p>
<ul>
<li>加快搜索速度——基于算法的改进KDTree,API接口里面有实现</li>
<li>knn算法fit的时候，不进行任何参数计算，仅仅是保存训练集，为测试集提供参照样本。</li>
<li>极端情况，即邻居个数等于训练集中所有数据的个数，那么每个测试点的邻居都是除自己外的所有样本，就会出现预测结果完全相同（即集中出现次数最多的类别，也就是所有样本都属于一个类别）</li>
<li>k=1时，模型复杂度最高，决策边界越复杂，但是k也不能一直变大，效果会大幅降低，需要寻找合适的k值，一般三五个都没问题
除了常用方法外，还有个predict_proba(x_test) 用于返回测试数据X属于某一类别的概率估计</li>
</ul>
<h3 id="knn">knn算法优缺点<a class="headerlink" href="#knn" title="Permanent link"></a></h3>
<h4 id="_40">优点：<a class="headerlink" href="#_40" title="Permanent link"></a></h4>
<ul>
<li>基于实例的学习，无需训练</li>
<li>简单，易于理解，易于实现，无需估计参数，无需训练（不存在迭代过程，比如第一次准确率不高，就迭代一次）</li>
<li>knn算法的准确度还是相当高的，此算法的有效性可以</li>
</ul>
<h4 id="_41">缺点：<a class="headerlink" href="#_41" title="Permanent link"></a></h4>
<ul>
<li>懒惰算法，对测试样本分类时的计算量大，内存开销大</li>
<li>必须指定K值，K值选择不当则分类精度不能保证</li>
<li>使用场景：小数据场景，几千～几万样本，具体场景具体业务去测试</li>
<li>当样本不平衡时，如一个类的样本容量很大，而其他类样本容量很小时，有可能导致当输入一个新样本时，该样本的K个邻居中大容量类的样本占多数，就导致任何样本的分类都是一类了</li>
<li>对于有很多特征（几百或更多）的数据集往往效果不好，对于大多数特征的大多数取值都为 0 的数据集（所谓的稀疏数据集）来说，这一算法的效果尤其不好。</li>
</ul>
<h3 id="knn_1">knn的计算结果<a class="headerlink" href="#knn_1" title="Permanent link"></a></h3>
<ul>
<li>计算结果是直接给出每个样本的所属分类，不给出属于此分类的占比</li>
<li>此处的占比和概率类似，因为是要从k个近邻中选出哪个类别的样本多，据此预测</li>
<li>简单说，就是被预测的样本，和哪几个近邻最相似，他就属于哪个类别</li>
</ul>
<h2 id="knn_2">knn回归算法<a class="headerlink" href="#knn_2" title="Permanent link"></a></h2>
<p>寻找k个最近邻，求解这几个近邻的目标值的（加权）平均值为当前样本的预测值</p>
<h3 id="knnapi">knn回归算法api<a class="headerlink" href="#knnapi" title="Permanent link"></a></h3>
<p><code>from sklearn.neighbors import KNeighborsRegressor</code>
参数常用的有：n_neighbors   含义和分类算法一致
weights：distance，uniform（默认值），两者区别在于前者依据预测样本与k个近邻的距离远近进行加权，即结果受最近的点的影响较大；uniform则是按相同的权重求平均值得出预测值。两者可以对比选取，并非哪个就一定好</p>
<h2 id="_42">朴素贝叶斯<a class="headerlink" href="#_42" title="Permanent link"></a></h2>
<ul>
<li>一般就用在文本分类</li>
<li>朴素一词的来源就是假设各特征之间相互独立</li>
</ul>
<p>sklearn中有3种不同类型的朴素贝叶斯：
+ 高斯分布型：用于classification问题，假定属性/特征服从正态分布的。
+ 多项式型：用于离散值模型里。比如文本分类问题里面我们提到过，我们不光看词语是否在文本中出现，也得看出现次数。如果总词数为n，出现词数为m的话，有点像掷骰子n次出现m次这个词的场景。
+ 伯努利型：最后得到的特征只有0(没出现)和1(出现过)。
此处着重讲解多项式型，是关于文本分类的应用</p>
<p>详见：<a href="https://blog.csdn.net/fisherming/article/details/79509025">https://blog.csdn.net/fisherming/article/details/79509025</a></p>
<h3 id="_43">概率基础<a class="headerlink" href="#_43" title="Permanent link"></a></h3>
<ul>
<li>联合概率：包含多个条件（条件之间相互独立，互不影响），且所有条件<strong>同时</strong>成立的概率，记作：𝑃(𝐴,𝐵)</li>
<li>
<p>条件概率：就是事件A在另外一个事件B已经发生条件下的发生概率，记作：𝑃(𝐴|𝐵)</p>
</li>
<li>
<p>特性：P(A1,A2|B) = P(A1|B)P(A2|B)，注意：此条件概率的成立，是由于A1,A2相互独立的结果</p>
</li>
<li>使用此算法的条件：所有特征之间假设是独立的（即条件独立）</li>
</ul>
<h3 id="_44">朴素贝叶斯公式<a class="headerlink" href="#_44" title="Permanent link"></a></h3>
<p>p(c|w) = p(w|c)p(c) / p(w)
注：w为给定文档的特征值(频数统计,预测文档提供)，c为文档类别
公式可以理解为：
    𝑃(𝐶|𝐹1,𝐹2,…)=(𝑃(𝐹1,𝐹2,… │𝐶)𝑃(𝐶)) / (𝑃(𝐹1,𝐹2,…))
公式分为三个部分：
    𝑃(𝐶)：每个类别的概率(某类别的文档数／总文档数)
    𝑃(𝑊│𝐶)：给定类别下 每个特征（被预测文档中出现的词）的概率
        计算方法：𝑃(𝐹1│𝐶)=𝑁𝑖/𝑁   （训练文档中去计算）
        𝑁𝑖为该𝐹1词在C类别所有文档中出现的次数
        N为所属类别C下的文档所有词出现的次数和
    𝑃(𝐹1,𝐹2,…)     预测文档中每个词的概率 </p>
<p>理解案例：
    出现影院，支付宝，云计算词汇的文档，属于科技，娱乐的概率分别是多少
    p(影院，支付宝，云计算|科技) * p (科技)
    = p(影院|科技) * p(支付宝|科技) * p(云计算|科技) * p(科技)
    = 9/101 * 21/101 * 64/101 * (30/90) = 362880/92727090
    = 0.0039</p>
<div class="codehilite"><pre>p(影院，支付宝，云计算|娱乐) * p (娱乐)
= p(影院|娱乐) * p(支付宝|娱乐) * p(云计算|娱乐) * p(娱乐)
= 57/122 * 16/122 * 1/122 * (60/90) = 54720/163426320
= 0.00033
</pre></div>


<ul>
<li>拉普拉斯系数不会对结果造成影响，概率本来大的还是会大，仅仅是取消了概率为0的出现，此值非超参数</li>
<li>此算法没有超参数可以调优，只是对数据集的要求高，直接影响预测的效果</li>
</ul>
<p>出现的疑问：算法似乎忽略了每篇文章中不同词汇出现的次数
自行解释：作为计算的数据，已经是将所有文章进行统计后的数据，已经表明了只要某个文章出现某个词汇他就有属于这个类别的概率存在了。有点绕，大概是这么个意思，计算忽视了单个样本中词出现的次数，而是以统计的所有文章中出现此词的次数为依据</p>
<p>knn算法是以每个样本之间的计算为依据，贝叶斯是以所有样本统计后的数据作为计算的依据</p>
<h3 id="api_2">api<a class="headerlink" href="#api_2" title="Permanent link"></a></h3>
<p><code>sklearn.naive_bayes.MultinomialNB(alpha = 1.0)</code> alpha：拉普拉斯平滑系数
fit的时候，是去进行统计词这些工作的计算</p>
<h3 id="_45">预测结果<a class="headerlink" href="#_45" title="Permanent link"></a></h3>
<ul>
<li>结果是比较属于每个类别的概率大小，比较大小取最大者为其类别，和knn区别在于这里的概率值可能都很小，和不为1，knn是看k个近邻中占比多的那个类别为其类别，和为1</li>
</ul>
<h3 id="_46">朴素贝叶斯案例流程<a class="headerlink" href="#_46" title="Permanent link"></a></h3>
<p>1、加载20类新闻数据，并进行分割（训练集，测试集划分）
2、生成文章特征词（特征抽取）
3、朴素贝叶斯estimator流程进行预估（估计器预测）</p>
<h3 id="_47">朴素贝叶斯分类优缺点<a class="headerlink" href="#_47" title="Permanent link"></a></h3>
<ul>
<li>
<p>优点：</p>
<ul>
<li>朴素贝叶斯模型发源于古典数学理论，有稳定的分类效率。</li>
<li>对缺失数据不太敏感，算法也比较简单，常用于文本分类。</li>
<li>分类准确度高，速度快</li>
</ul>
</li>
<li>
<p>缺点：</p>
<ul>
<li>需要知道先验概率P(F1,F2,…|C)，因此在某些时候会由于假设的先验（假设条件独立）</li>
<li>模型的原因导致预测效果不佳（也就是数据集的原因）</li>
</ul>
</li>
</ul>
<h2 id="_48">贝叶斯进阶<a class="headerlink" href="#_48" title="Permanent link"></a></h2>
<p>算法已有几百年
贝叶斯要解决的问题：
男生：60%
女生：40%
男生总是穿长裤，女生则一半穿长裤一半穿裙子
正向概率：随机选取一个学生，他（她）穿长裤的概率和穿裙子的概率是多大
逆向概率：迎面走来一个穿长裤的学生，你只看得见他（她）穿的是否长裤，而无法确定他（她）的性别，你能够推断出他（她）是女生的概率是多大吗？</p>
<p><strong>以下为算法的推导过程</strong> 
此处的逆向概率就是贝叶斯算法要解决的问题，通过这个例子可以<strong>推导出贝叶斯公式</strong>
穿长裤是女生的概率=女生长裤人数/长裤总人数
问题变为求长裤总人数和女生长裤人数，假设总人数为n
长裤总人数=0.6n + 0.4n × 0.5
女生长裤人数= 0.4n × 0.5
穿长裤女生概率 = (0.4n × 0.5) / (0.6n + 0.4n × 0.5)</p>
<p><strong>p(女生|长裤)= p(女生) × p(长裤|女生)/p(长裤)</strong> 即是贝叶斯公式
其中p(女生)和p(长裤)算是已知条件，即先验概率
先验概率:是指根据以往经验和分析得到的概率
而p(长裤|女生)则是条件概率</p>
<h2 id="_49">分类模型的评估<a class="headerlink" href="#_49" title="Permanent link"></a></h2>
<h3 id="_50">混淆矩阵<a class="headerlink" href="#_50" title="Permanent link"></a></h3>
<ul>
<li>在分类任务下，预测结果(Predicted Condition)与正确标记(True Condition)之间存在四种不同的组合，构成混淆矩阵(适用于多分类)</li>
<li>举例：癌症（正例）与非癌症（反例）
四种组合：真实情况是癌症，预测结果有两者，要么是癌症（预测正确），要么不是；真实情况非癌症，预测结果也有两个，要么是癌症，要么非癌症（预测正确）</li>
</ul>
<h3 id="precisionrecall">精确率(Precision)与召回率(Recall)<a class="headerlink" href="#precisionrecall" title="Permanent link"></a></h3>
<ul>
<li>一般情况使用准确率就能表现模型的效果，有时的场景还不能完全表现，就需要以下两种指标</li>
<li>
<p>精确率（用的不多）：预测结果为正例样本中，真实为正例的比例（查得准）</p>
<ul>
<li>理解举例：预测结果中有20个癌症，这20个中真正是癌症的有16个，精确率就是16/20=0.8
召回率（提高此值）：真实为正例的样本中，预测结果为正例的比例（查的全，对正样本的区分能力）</li>
<li>理解举例：原本真实情况有20个癌症，这20个人中，被预测出是癌症的有16人，召回率16/20=0.8</li>
</ul>
</li>
<li>
<p>其他分类标准，F1-score，反映了模型的稳健型</p>
</li>
</ul>
<h3 id="api_3">分类模型评估API<a class="headerlink" href="#api_3" title="Permanent link"></a></h3>
<p><code>sklearn.metrics.classification_report(y_true, y_pred, labels=[0,1],target_names=['良性','恶性'])</code>
    y_true：真实目标值
    y_pred：估计器预测目标值
    labels:和target_names相对应的类别符号（如0，1，其中0代表良性，1代表恶性）
    target_names：目标类别名称（在结果中显示，用来更清晰的观察结果）
    return：每个类别精确率与召回率</p>
<h3 id="_51">模型的选择与调优<a class="headerlink" href="#_51" title="Permanent link"></a></h3>
<h4 id="_52">交叉验证<a class="headerlink" href="#_52" title="Permanent link"></a></h4>
<ul>
<li>目的：为了让被评估的模型更加准确可信</li>
<li>将原数据集分割后的训练集数据，再次分为训练集和验证集。举例如：将原训练集分成5份，其中一份作为验证集。然后经过5次(组)的测试，每次都更换不同的验证集。即得到5组模型的结果（每次交叉验证得到的默认是score的结果，也就是准确率），取平均值作为最终结果。又称5折交叉验证。</li>
<li>一般取10折交叉验证</li>
<li>依据每次验证的结果之和求平均值
交叉验证api：<a href="http://sklearn.apachecn.org/cn/0.19.0/modules/cross_validation.html">http://sklearn.apachecn.org/cn/0.19.0/modules/cross_validation.html</a>
一般不单独使用交叉验证，而是与网格搜索结合使用，以得到最佳超参数</li>
</ul>
<h4 id="_53">两种交叉验证的方式：<a class="headerlink" href="#_53" title="Permanent link"></a></h4>
<p><code>cross_val_score</code> 一般用于获取每折的交叉验证的得分，然后根据这个得分为模型选择合适的超参数，通常需要编写循环手动完成交叉验证过程；
<code>GridSearchCV</code> 除了自行完成叉验证外，还返回了最优的超参数及对应的最优模型所以相对于cross_val_score来说，GridSearchCV在使用上更为方便；但是对于细节理解上，手动实现循环调用cross_val_score会更好些。</p>
<h4 id="_54">网格搜索（超参数搜索）<a class="headerlink" href="#_54" title="Permanent link"></a></h4>
<ul>
<li>通常情况下，有很多参数是需要手动指定的（如k-近邻算法中的K值），这种叫超参数。但是手动过程繁杂，所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。</li>
</ul>
<h4 id="api_4">api<a class="headerlink" href="#api_4" title="Permanent link"></a></h4>
<p><code>sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)</code>
+ 对估计器的指定参数值进行详尽搜索
+ estimator：估计器对象
+ param_grid：估计器参数(dict){“n_neighbors”:[1,3,5]}
+ cv：指定几折交叉验证
+ fit：输入训练数据
+ score：准确率
结果分析：
+ best_score_:最佳参数模型时，交叉验证的平均值（非最高值）
+ best_estimator_：最好的参数模型
+ cv_results_:每次交叉验证后验证集的准确率结果和训练集准确率结果  <br />
老版本的没有这个但是有个grid_scores_  类似效果</p>
<ul>
<li>在需要超参数调优时，才会考虑使用交叉验证和网格搜索，当没有超参数需要调整时，时不需要进行此项操作的</li>
<li>注意param_grid 有多个超参数时，超参数的个数不是要求一样的。进行超参数组合时，是计算所有参数的笛卡尔积进行的，也就是计算的次数，如两个参数n_estimators和max_depth，前者有6个数据，后者有5个，则有30次组合来计算</li>
</ul>
<h2 id="_55">决策树<a class="headerlink" href="#_55" title="Permanent link"></a></h2>
<p>决策树思想的来源非常朴素，程序设计中的条件分支结构就是if-else结构，最早的决策树就是利用这类结构分割数据的一种分类学习方法 </p>
<h4 id="_56">树的组成<a class="headerlink" href="#_56" title="Permanent link"></a></h4>
<p>根节点：第一个选择点，最重要的特征（信息增益最大或者基尼系数最小的特征）
非叶子节点与分支：中间过程
叶子节点：最终的决策结果</p>
<h3 id="_57">决策树的训练与测试<a class="headerlink" href="#_57" title="Permanent link"></a></h3>
<p>1、训练阶段：从给定的训练集构造出来一棵树（从根节点开始选择特征，如何进行特征切分）
2、测试阶段：根据构造出来的树模型从上到下去走一遍就好了
3、一旦构造好了决策树，那么分类或者预测任务就很简单了，只需要走一遍就可以了，那么难点就在于如何构造出来一颗树，这就没那么容易了，需要考虑的问题还有很多的！</p>
<h3 id="_58">信息熵（衡量标准，谁来做根节点，第二个节点等等一直排下去）<a class="headerlink" href="#_58" title="Permanent link"></a></h3>
<p>H = -(p1logp1 + p2logp2 + &hellip; + p32log32)
H的专业术语称之为信息熵，单位为比特。</p>
<p>信息熵也是一种代价，如猜测32支球队，在无任何信息的情况下，猜对某个球队得冠军最多需要五次，即5比特，这个5就是信息熵
当知道一些信息的情况下，也就是32支球队，每个队伍获的冠军的概率是不同的，如此求的的信息熵就比最大的信息熵要小，信息熵越小，不确定性就越小</p>
<p>当得知某个特征的信息前提下，对信息熵的减小量，是<strong>信息增益</strong>（决策树划分特征重要性的依据）
特征A对训练数据集D的信息增益g(D,A),定义为集合D的信息熵H(D)与特征A给定条件下D的信息熵H(D|A)之差，即公式为 g(D, A) = H(D) - H(D|A)
H(D) 为初始信息熵，H(D|A)是在特征A知道的前提下（如是否有房子），求得的信息熵
注：信息增益表示得知特征X的信息而使得Y的信息的不确定性减少的程度
从中可以看出，信息增益越大，表明这个特征越重要，也就是在知道这个特征的前提下，信息熵会大幅减小</p>
<p>理解信息熵的计算方式：
1、如猜测球队冠军，目的是得到冠军是谁，32种结果，相加32次，每个概率均等
2、是否发放贷款，目的是是否放贷，2种结果，相加2次，每个概率根据历史数据得出，如有历史15人的数据，9人放贷，6人不放，概率就是6/15,9/15
3、信息增益计算时，在得知某个特征的概率的前提下，求在此特征下的信息熵，如青年占比5/15，这5人中贷款2人，未贷3人，那么在此条件下信息熵就是 <code>-5/15*(2/5log2/5+3/5log3/5)</code></p>
<p><strong>结论：信息熵越大，可选择性更多，不确定性越大；信息增益越大，特征越重要，在树上的体现就是越靠上。</strong></p>
<h3 id="_59">常见决策树使用的算法<a class="headerlink" href="#_59" title="Permanent link"></a></h3>
<p>1、ID3 信息增益；
存在的问题：如果某一个特征，如主键id，均不相同，当以此为一个特征时，有几个id，就会分出几个叶节点，导致当知道此特征的情况下，计算的信息熵全为0，如此就导致信息增益最大，那么这个特征就变成最重要的了，可是实际上这个是无意义的特征。
2、C4.5 信息增益比：用于解决信息增益存在的问题，除了计算在得知此特征情况下，还要计算特征自身的信息熵，也就是会划分特别多的目标（类似于32支球队，每队都有获胜可能），求得的信息熵特别大
3、CART 使用GINI系数当作衡量标准
基尼系数计算：1-sigma(p^2)  也就是1减去一个概率值，概率越大（不确定性越小），基尼系数越小</p>
<h3 id="api_5">api<a class="headerlink" href="#api_5" title="Permanent link"></a></h3>
<p>class sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)
决策树分类器
criterion:默认是’gini’系数，也可以选择信息增益的熵’entropy’
max_depth:树的深度大小
min_samples_split:如果某节点的样本数少于此值，则不会继续再尝试选择最优特征进行划分，如果样本量不大，不需要管这个值，如果样本量非常大，则推荐增大这个值
min_samples_leaf：限制叶子节点最少的样本数，如果某叶子节点数目小于样本数，则会和兄弟节点一起被剪枝，如果样本量不大，不需要管这个值，大些如10w可尝试下5
random_state:随机数种子</p>
<p>method:
decision_path:返回决策树的路径</p>
<h3 id="_60">决策树的优缺点以及改进<a class="headerlink" href="#_60" title="Permanent link"></a></h3>
<p>优点：
简单的理解和解释，树木可视化。
需要很少的数据准备，其他技术通常需要数据预处理。 </p>
<p>缺点：
决策树学习者可以创建不能很好地推广数据的过于复杂的树，这被称为过拟合。
决策树可能不稳定，因为数据的小变化可能会导致完全不同的树被生成</p>
<p>过拟合的风险很大，不加限制，默认会将训练集的所有数据全部分类，过于细致，就会导致测试集的效果很差</p>
<p>改进：
剪枝cart算法，一般限制树的深度
预剪枝：限制深度，控制叶子节点个数等
后剪枝：用的少</p>
<p>随机森林</p>
<h3 id="_61">决策树的图形保存<a class="headerlink" href="#_61" title="Permanent link"></a></h3>
<p>树中保存的结构是训练集数据得出的
测试集的数据是否是将每个样本按此树进行划分得到最终结果，如何划分呢？</p>
<p>1、sklearn.tree.export_graphviz() 该函数能够导出DOT格式
tree.export_graphviz(estimator,out_file=&rsquo;tree.dot’,feature_names=[‘’,’’])
feature_names是get_feature_names得到的列表，可以修改为中文</p>
<p>2、工具:(能够将dot文件转换为pdf、png)
安装graphviz
ubuntu:sudo apt-get install graphviz                    Mac:brew install graphviz
windows：<a href="https://blog.csdn.net/witnessai1/article/details/52923025">https://blog.csdn.net/witnessai1/article/details/52923025</a>
3、运行命令
然后我们运行这个命令
$ dot -Tpng tree.dot -o tree.png</p>
<h2 id="_62">集成学习方法<a class="headerlink" href="#_62" title="Permanent link"></a></h2>
<p>集成学习通过建立几个模型组合来解决单一预测问题。它的工作原理是生成多个分类器模型，各自独立地学习和作出预测。这些预测最后结合成单预测，因此优于单个模型做出的预测。
三种分类，每种代表一种思想：
1、Bagging：训练多个分类器取平均值，典型就是随机森林，是一种并行的算法（每个树可以独立运行）
理论上越多树效果会越好，实际上超过一定数量就开始上下浮动 100左右就差不多了
2、Boosting（提升模型）：从弱学习器开始加强，通过加权来进行训练，是一种串行的算法（后一个树依赖于前一个树的结果），通过多次计算得到较好的效果，代表adaboost，xgboost
3、tacking（堆叠算法）：聚合多个分类或回归模型（分阶段来做）
可以堆叠各种各样的分类器
分阶段：第一阶段得出每个分类器的结果，第二阶段再用第一阶段得到的结果作为样本进行训练
堆叠在一起确实能使得准确率提升，但是速度是个问题
<strong>集成算法是竞赛与论文神器</strong>，当我们更关注于结果时不妨来试试！</p>
<h3 id="_63">随机森林<a class="headerlink" href="#_63" title="Permanent link"></a></h3>
<p>在机器学习中，随机森林是一个包含多个决策树的分类器，并且其输出的类别是由个别树输出的类别的众数而定。（即以所有树中占多数的预测结果为最后结果，有点类似k近邻的取结果方式）
例如, 如果你训练了5个树, 其中有4个树的结果是True, 1个数的结果是False, 那么最终结果会是True.</p>
<p>随机的理解：
一次随机抽样，会从特征中抽取部分特征作为此数据集的特征值，随机从所有样本选取部分样本作为数据样本，两者组成一次随机抽样的结果。
以上过程进行多次，就构成了多个决策树，组成随机森林</p>
<h4 id="_64">算法实现过程<a class="headerlink" href="#_64" title="Permanent link"></a></h4>
<p>根据下列算法而建造每棵树：
+ 用N来表示训练集的样本个数，M表示特征数量。
+ 输入特征数量 m，用于确定决策树上 一个节点的决策结果；其中m应远小于M。（也就是取出m个特征，以这m个特征来进行决策）
+ 从N个训练样本中以<strong>有放回抽样</strong>的方式，取样N次，形成一个训练集（即bootstrap取样），并用未抽到的样本作预测，评估其误差。（注意因为是有放回的抽样，因此重复N次的情况下，数据是有可能重复的）</p>
<p><strong>为什么要随机抽样训练集？</strong>
如果不进行随机抽样，每棵树的训练集都一样，那么最终训练出的树分类结果也是完全一样的</p>
<p><strong>为什么要有放回地抽样？</strong>
　　如果不是有放回的抽样，那么每棵树的训练样本都是不同的，都是没有交集的，这样每棵树都是“有偏的”，都是绝对“片面的”（当然这样说可能不对），也就是说每棵树训练出来都是有很大的差异的；而随机森林最后分类取决于多棵树（弱分类器）的投票表决。</p>
<h4 id="api_6">api<a class="headerlink" href="#api_6" title="Permanent link"></a></h4>
<p>class sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’,max_depth=None, bootstrap=True, random_state=None)
随机森林分类器
    n_estimators：integer，optional（default = 10） 森林里的树木数量
        常用的数量120，200，300，500，800
    criteria：string，可选（default =“gini”）分割特征的测量方法
    max_depth：integer或None，可选（默认=无）树的最大深度 
    常用深度5，8，15，25，30
    max_features=”auto” 每个决策树的最大特征数量
        if auto ,then sqrt(n_features)
        if log2  then log2(n_features)
        if none  then  n_features
    bootstrap：boolean，optional（default = True）是否在构建树时使用有放回抽样 </p>
<h4 id="_65">随机森林的优点<a class="headerlink" href="#_65" title="Permanent link"></a></h4>
<p>在当前所有算法中，具有极好的<strong>准确率</strong>
能够有效地运行在<strong>大数据集</strong>上
能够处理具有高维特征的输入样本，而且<strong>不需要降维</strong>
能够评估各个<strong>特征</strong>在分类问题上的<strong>重要性</strong>
对于缺省值问题也能够获得很好得结果
训练完成后，能够给出哪些特征比较重要，dt.feature_importance_可以得到重要性指标</p>
<h2 id="_66">线性回归<a class="headerlink" href="#_66" title="Permanent link"></a></h2>
<h3 id="_67">线性模型<a class="headerlink" href="#_67" title="Permanent link"></a></h3>
<p>试图学得一个通过<strong>属性的线性组合</strong>来进行预测的函数：
𝑓(𝑥)=𝑤1𝑥1+𝑤2𝑥2+…+𝑤𝑑 𝑥𝑑+𝑏
w为权重，b称为偏置项，可以理解为：𝑤0×1</p>
<h3 id="_68">线性回归算法<a class="headerlink" href="#_68" title="Permanent link"></a></h3>
<p>定义：线性回归通过一个或者多个自变量与因变量之间之间进行建模的回归分析。其中特点为一个或多个称为回归系数的模型参数的线性组合</p>
<p>一元线性回归：涉及到的变量只有一个
多元线性回归：涉及到的变量两个或两个以上
（以上变量的理解，自变量即为特征，因变量即为目标值，回归系数就是求的权重）</p>
<p>通用公式：h(w) = w0x0 + w1x1 + w2x2 + &hellip; = wTx
注意：式子中的x0，相当于是给原数据增加了一个特征，这个特征的每个值都为1</p>
<p>预测结果与真实值是有一定的误差</p>
<h3 id="_69">矩阵乘法<a class="headerlink" href="#_69" title="Permanent link"></a></h3>
<ul>
<li>为何要使用矩阵？如果是普通的for循环来计算每个，时间复杂度很高，矩阵运算更加高效
<code>(m行,l列)*(l行,n列) = (m行,n列)</code></li>
</ul>
<p>[
    [1,2,3,4]
    [5,6,7,8]      *    [[2],[2],[2],[2]]
]
(2,4) * (4,1) = (2,1)</p>
<p>理解：每个特征都有对应的权重，第一个数组是特征，第二个数组是权重，矩阵运算整好符合这种运算</p>
<h3 id="_70">误差（进阶）<a class="headerlink" href="#_70" title="Permanent link"></a></h3>
<p>误差 是<strong>独立</strong>并且具有<strong>相同的分布</strong>，并且服从均值为0方差为 sita平方 的高斯分布
    独立：张三和李四一起来贷款，他俩没关系（样本间独立？）
    同分布：他俩都来得是我们假定的这家银行（样本使用同一套模型进行预测）
    高斯分布：银行可能会多给，也可能会少给，但是绝大多数情况下这个浮动不会太大，极小情况下浮动会比较大，符合正常情况（通常现实生活中也符合此情况，类似二八定律，大多人没钱，少数人有钱）
以上的独立，同分布，高斯分布（正态分布）都是基于假设，现实没有完全符合的，只是基于此假设得到的结论基本符合正常情况，因此这种假设是合理的</p>
<h3 id="_71">损失函数(误差大小)<a class="headerlink" href="#_71" title="Permanent link"></a></h3>
<p>J(sita) = (h(x1)-y1)^2 + (h(x2)-y2)^2 + &hellip; + (h(xm)-ym)^2 
𝑦𝑖为第𝑖个训练样本的真实值</p>
<p>h(xi)为第𝑖个训练样本特征值组合预测函数</p>
<p>称为最小二乘法，理解就是以 预测值和真实值之差的平方（类似k近邻算法的计算，k近邻开根号），注意不开根号</p>
<ul>
<li>线性回归的目的，去寻找合适的w，使得损失函数最小</li>
</ul>
<h3 id="_72">最小二乘法之正规方程(不做要求)<a class="headerlink" href="#_72" title="Permanent link"></a></h3>
<p>api是<code>sklearn.linear_model.LinearRegression()</code>
可以设置参数normalize:如果设置为True时，数据进行标准化。
此标准化与自己进行标准化得到的结果完全一致，省去了自己标准化的麻烦处理
代码对比见下：
<div class="codehilite"><pre><span class="k">def</span> <span class="nf">l</span><span class="p">():</span>
    <span class="n">b</span> <span class="o">=</span> <span class="n">load_boston</span><span class="p">()</span>
    <span class="n">x</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="n">data</span>
    <span class="n">y</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="n">target</span>
    <span class="n">x_train</span><span class="p">,</span> <span class="n">x_test</span><span class="p">,</span> <span class="n">y_train</span><span class="p">,</span> <span class="n">y_test</span> <span class="o">=</span> <span class="n">train_test_split</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">test_size</span><span class="o">=</span><span class="mf">0.25</span><span class="p">,</span> <span class="n">random_state</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="n">x_train</span><span class="p">)</span>
    <span class="n">lr</span> <span class="o">=</span> <span class="n">LinearRegression</span><span class="p">(</span><span class="n">normalize</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">lr</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">x_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
    <span class="n">y_pred</span> <span class="o">=</span> <span class="n">lr</span><span class="o">.</span><span class="n">predict</span><span class="p">(</span><span class="n">x_test</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="n">y_pred</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">l2</span><span class="p">():</span>
    <span class="n">b</span> <span class="o">=</span> <span class="n">load_boston</span><span class="p">()</span>
    <span class="n">x</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="n">data</span>
    <span class="n">y</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="n">target</span>
    <span class="n">x_train</span><span class="p">,</span> <span class="n">x_test</span><span class="p">,</span> <span class="n">y_train</span><span class="p">,</span> <span class="n">y_test</span> <span class="o">=</span> <span class="n">train_test_split</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">test_size</span><span class="o">=</span><span class="mf">0.25</span><span class="p">,</span> <span class="n">random_state</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="n">x_train</span><span class="p">)</span>
    <span class="c1"># 手动进行标准化处理</span>
    <span class="n">xs</span> <span class="o">=</span> <span class="n">StandardScaler</span><span class="p">()</span>
    <span class="n">x_train</span> <span class="o">=</span> <span class="n">xs</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">x_train</span><span class="p">)</span>
    <span class="n">x_test</span> <span class="o">=</span> <span class="n">xs</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">x_test</span><span class="p">)</span>
    <span class="n">ys</span> <span class="o">=</span> <span class="n">StandardScaler</span><span class="p">()</span>
    <span class="c1"># 注意目标值的标准化需要时二维数组</span>
    <span class="n">y_train</span> <span class="o">=</span> <span class="n">ys</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">y_train</span><span class="o">.</span><span class="n">reshape</span><span class="p">((</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span>
    <span class="n">y_test</span> <span class="o">=</span> <span class="n">ys</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">y_test</span><span class="o">.</span><span class="n">reshape</span><span class="p">((</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span>

    <span class="n">lr</span> <span class="o">=</span> <span class="n">LinearRegression</span><span class="p">()</span>
    <span class="n">lr</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">x_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
    <span class="n">y_pred</span> <span class="o">=</span> <span class="n">lr</span><span class="o">.</span><span class="n">predict</span><span class="p">(</span><span class="n">x_test</span><span class="p">)</span>
    <span class="c1"># flatten扁平化处理，将高维数据转为一维数据</span>
    <span class="k">print</span><span class="p">(</span><span class="n">ys</span><span class="o">.</span><span class="n">inverse_transform</span><span class="p">(</span><span class="n">y_pred</span><span class="p">)</span><span class="o">.</span><span class="n">flatten</span><span class="p">())</span>
</pre></div></p>
<p>求解：𝑤=〖(𝑋〗^𝑇 〖𝑋)〗^(−1) 𝑋^𝑇 𝑦
𝑋为特征值矩阵，𝑦为目标值矩阵</p>
<p>缺点：当特征过于复杂，求解速度太慢,对于复杂的算法，不能使用正规方程求解(逻辑回归等)</p>
<h3 id="_73">最小二乘法之梯度下降(理解过程)<a class="headerlink" href="#_73" title="Permanent link"></a></h3>
<p><strong>𝛼为学习速率，需要手动指定</strong>
理解：沿着这个函数下降的方向找，最后就能找到山谷的最低点，然后
更新W值
使用：面对训练数据规模十分庞大的任务</p>
<p><strong>注意：正规方程和梯度下降的公式计算得到的是w值，看什么样的w值使得损失函数最小，就以此时的w作为最后结果</strong></p>
<p><strong>线性回归的目的就是去求出使得损失函数最小的w值</strong>
梯度下降的api中，可以传递的参数有很多，有正则化选项如l1，l2，默认是l2，还有正则化力度alpha，初始学习率是参数eta0</p>
<p><strong>梯度下降没有标准化的参数，和正规方法的api不同，因此这个需要自行标准化处理</strong></p>
<h3 id="_74">正规方程与梯度下降的对比<a class="headerlink" href="#_74" title="Permanent link"></a></h3>
<h4 id="sklearnapi_1">sklearn线性回归正规方程、梯度下降API<a class="headerlink" href="#sklearnapi_1" title="Permanent link"></a></h4>
<p>sklearn.linear_model.LinearRegression<br />
    正规方程  数据小
sklearn.linear_model.SGDRegressor
    梯度下降  数据大
sklearn.linear_model.LinearRegression()
    普通最小二乘线性回归
    coef_：回归系数 
sklearn.linear_model.SGDRegressor( )
    通过使用SGD最小化线性模型
    coef_：回归系数  coefficient  koui&rsquo;fishnt
回归系数就是最后求的w</p>
<h4 id="_75">波士顿房价数据案例分析流程<a class="headerlink" href="#_75" title="Permanent link"></a></h4>
<p>1、波士顿地区房价数据获取
2、波士顿地区房价数据分割
3、训练与测试数据标准化处理
4、使用最简单的线性回归模型LinearRegression和梯度下降估计SGDRegressor对房价进行预测</p>
<ul>
<li>注意需要进行标准化处理，特征值处理后，因为是要得出线性结果，要求出w值，目标值也要进行标准化，将特征值和目标值缩放到一个数量级</li>
</ul>
<h3 id="_76">回归性能评估<a class="headerlink" href="#_76" title="Permanent link"></a></h3>
<p>(均方误差(Mean Squared Error)MSE) 评价机制：
实质就是损失函数除以总的样本数，损失函数是所有样本损失总和，而均方误差是求得的平均值</p>
<h3 id="sklearnapi_2">sklearn回归评估API<a class="headerlink" href="#sklearnapi_2" title="Permanent link"></a></h3>
<p>mean_squared_error(y_true, y_pred)
    均方误差回归损失
    y_true:真实值
    y_pred:预测值
    return:浮点数结果
注：真实值，预测值为标准化之前的值，需要对标准化的值进行逆向转换，包括预测结果</p>
<p>线性回归特点：线性回归器是最为简单、易用的回归模型。从某种程度上限制了使用，尽管如此，在不知道特征之间关系的前提下，我们仍然使用线性回归器作为大多数系统的首要选择。
小规模数据：LinearRegression(不能解决拟合问题)以及其它
大规模数据：SGDRegressor</p>
<h3 id="_77">出现的问题<a class="headerlink" href="#_77" title="Permanent link"></a></h3>
<p>梯度下降api在fit时，目标值如果是二维ndarray，需要将其降至一维ndarray，否则会提示警告，具体如下：
<div class="codehilite"><pre># 运行过程中出现警告的解决方法：https://blog.csdn.net/llx1026/article/details/77940880
sgd = SGDRegressor(max_iter=5)  # 这里是不同版本的sklearn，默认的max_iter不一致，会提示警告
sgd.fit(x_train, y_train.ravel())  # 将二维ndarray数组降至一维ndarray，还可以使用flatten()，达到同样的效果
</pre></div></p>
<h3 id="_78">过拟合与欠拟合<a class="headerlink" href="#_78" title="Permanent link"></a></h3>
<h4 id="_79">过拟合<a class="headerlink" href="#_79" title="Permanent link"></a></h4>
<p>一个假设在训练数据上能够获得比其他假设更好的拟合，但是在训练数据外的数据集上却不能很好地拟合数据，此时认为这个假设出现了过拟合的现象。(模型过于复杂)</p>
<h4 id="_80">过拟合原因以及解决办法<a class="headerlink" href="#_80" title="Permanent link"></a></h4>
<p>原因：
原始特征过多，存在一些嘈杂特征， 模型过于复杂是因为模型尝试去兼顾各个测试数据点，导致对训练集效果极好，但是对测试集效果较训练集差</p>
<p>可通过训练集的交叉验证观察，是否是在训练集的效果优于测试集</p>
<p>解决办法：
进行特征选择，消除关联性大的特征(很难做，看不出系数和特征几次方的关系 )
交叉验证(让所有数据都有过训练)
正则化(重点，特征选择的一种，使用此方式，尽量减小高次项特征的影响)</p>
<h4 id="l2">L2正则化<a class="headerlink" href="#l2" title="Permanent link"></a></h4>
<p>作用：可以使得W的每个元素都很小，都接近于0</p>
<p>优点：越小的参数说明模型越简单，越简单的模型则越不容易产生过拟合现象</p>
<h4 id="_81">欠拟合<a class="headerlink" href="#_81" title="Permanent link"></a></h4>
<p>一个假设在训练数据上不能获得更好的拟合，但是在训练数据外的数据集上也不能很好地拟合数据，此时认为这个假设出现了欠拟合的现象。(模型过于简单)</p>
<h4 id="_82">欠拟合原因以及解决办法<a class="headerlink" href="#_82" title="Permanent link"></a></h4>
<p>原因：
学习到数据的特征过少</p>
<p>解决办法：
增加数据的特征数量</p>
<h2 id="-ridge">带有正则化的线性回归-Ridge<a class="headerlink" href="#-ridge" title="Permanent link"></a></h2>
<p>解决过拟合
sklearn.linear_model.Ridge(alpha=1.0)
具有L2正则化的线性最小二乘法</p>
<ul>
<li>L1正则化(Lasso类)，是将某些特征的权重置为0，等于舍弃了一些特征，和特征选择类似。</li>
</ul>
<p>alpha:正则化力度，0-1，1-10，力度越大，权重愈加趋近于0
coef_:回归系数</p>
<h3 id="linearregressionridge">线性回归 LinearRegression（正规方程）与Ridge对比<a class="headerlink" href="#linearregressionridge" title="Permanent link"></a></h3>
<p>岭回归：回归得到的回归系数更符合实际，更可靠。另外，能让估计参数的波动范围变小，变的更稳定。在<strong>存在病态数据偏多</strong>的研究中有较大的实用价值。
注意：当数据集越来越大（不清楚大到什么程度叫大），线性回归的性能是可能追上岭回归的，对于足够大的数据集，过拟合的概率较低，因此显得L2正则化也就不那么重要了</p>
<h2 id="-">分类算法-逻辑回归<a class="headerlink" href="#-" title="Permanent link"></a></h2>
<p>使用场景：
- 广告点击率
- 判断用户的性别
- 预测用户是否会购买给定的商品类
- 判断一条评论是正面的还是负面的</p>
<p>从以上可以看出，逻辑回归一般用来解决二分类问题，对于多分类一般不用，逻辑回归是解决二分类问题的利器</p>
<p>逻辑回归与线性回归的公式一致，同样是特征与权重相乘求和</p>
<h3 id="sigmod">sigmod函数<a class="headerlink" href="#sigmod" title="Permanent link"></a></h3>
<p>输出：分布在[0,1]区间的概率值，默认0.5作为阈值
注：g(z)为sigmoid函数，也就是结果是0-1
z是通过逻辑回归求得的解（权重和特征相乘后相加的解，即普通的线性回归的公式） </p>
<h3 id="_83">逻辑回归的损失函数、优化(了解)<a class="headerlink" href="#_83" title="Permanent link"></a></h3>
<p>与线性回归原理相同（均方误差）,但由于是分类问题，损失函数不一样，只能通过梯度下降求解
使用对数似然损失表示，损失的值越小，那么预测的类别准确度更高（损失小，说明预测结果与真实值间的误差小，注意此处和信息增益不是一回事，信息增益越大，说明当前计算的特征越重要）</p>
<p>预测一项内容，结果只有0和1，那么预测一般看是0和1的概率哪个小，就以小的为目标进行预测是这个数的概率大小，具体说如预测是否得癌症（假设是癌症的概率小），那么对于一个新的测试数据，就预测他是癌症的概率，小于阈值，就不是癌症，大于阈值，就是癌症</p>
<h3 id="_84">逻辑回归算法实现的方式<a class="headerlink" href="#_84" title="Permanent link"></a></h3>
<p>和线性回归类似，在训练的时候，还是要找到很多权重值，然后在预测的时候，不是看通过训练的权重计算的到的值，而是以此计算值通过sigmod函数求出sigmod值，大于阈值的即视为预测正确，小于预测不正确，因此解决二分类问题十分适用</p>
<h3 id="api_7">api<a class="headerlink" href="#api_7" title="Permanent link"></a></h3>
<p>sklearn.linear_model.LogisticRegression(penalty=‘l2’, C = 1.0)
penalty是惩罚的意思，这里是正则化的意思，以哪种正则化进行处理，C是正则化的力度
Logistic回归分类器
coef_：回归系数</p>
<p>逻辑回归的api在判断属于哪个类别时，是以样本中哪个类别少来作为要判断的目标值，如样本中良性75%，恶性25%，那么在通过阈值判断时，大于0.5，说明的是恶性概率高，即如果是0.1，那么就不是恶性，而是良性</p>
<p>也就是说，不需要在api中指定阈值划分标准</p>
<h3 id="logisticregression">LogisticRegression总结<a class="headerlink" href="#logisticregression" title="Permanent link"></a></h3>
<p>应用：广告点击率预测、电商购物搭配推荐
优点：适合需要得到一个分类概率的场景
缺点：当特征空间很大时，逻辑回归的性能不是很好
（看硬件能力）</p>
<h1 id="k-means">k-means聚类<a class="headerlink" href="#k-means" title="Permanent link"></a></h1>
<p><a href="https://blog.csdn.net/Katherine_hsr/article/details/79382249">常见的六大聚类算法</a>
+ 一般是在分类之前进行，可以将数据按特征进行分类
只知道特征，不知道目标
注意理解k-means为何叫这名字？
以二维平面中的一堆散点来理解：k就是在这一堆点中随机选取的k个点，然后计算其他的每个点分别到这三个点的欧氏距离，取最近者划分类别，计算完毕，可得出k个类别，然后计算每个类别所有值的平均值mean，得出k个mean，<strong>计算这k个点与原本随机选取的k个点进行比较</strong>，如果与原本的点一致，则停止计算，分类完成，不一致，则以这k个mean所在位置为初始点，重复以上步骤</p>
<h2 id="k-means_1">k-means步骤<a class="headerlink" href="#k-means_1" title="Permanent link"></a></h2>
<p>1、随机设置K个特征空间内的点作为初始的聚类中心
2、对于其他每个点计算到K个中心的距离，未知的点选择最近的一个聚类中心点作为标记类别
3、接着对着标记的聚类中心之后，重新计算出每个聚类的新中心点（mean）
4、如果计算得出的新中心点与原中心点一样，那么结束，否则重新进行第二步过程
通过以上步骤可知为何叫k-means算法</p>
<h2 id="api_8">api<a class="headerlink" href="#api_8" title="Permanent link"></a></h2>
<p>sklearn.cluster.KMeans(n_clusters=8,init=‘k-means++’)
    n_clusters:开始的聚类中心数量，即k值，也就是最终会分成k个类别
    init:初始化方法，默认为&rsquo;k-means ++’
    max_iter:最大迭代次数，一般无需设置
属性：
km.labels_:每个点的类别
km.cluster_centers_:每个族群的中心点坐标</p>
<p>预测新数据属于哪个类别
pre = km.predict([[1,2],[2,3]])  注意需要是二维数组</p>
<p>几点说明：
同一组数据，同样的参数，得到相同的分类（每次计算时分类的label可能不同，但是画图显示仅仅是每个族群的颜色改变，位置并未改变，分类也并未改变）</p>
<h2 id="_85">性能评估<a class="headerlink" href="#_85" title="Permanent link"></a></h2>
<p>轮廓系数：
    计算公式：sc = (b-a)/max(b,a)
轮廓系数的直观理解：每个点到其他族群的<strong>所有样本</strong>（并非针对某一族群，是点到除自身族群外的其他所有数据）的平均值为b，到自身族群所有样本距离的平均值为a，如果b远大于a，那么sc就趋近于1，说明这个点与自己的族群更接近，与其他族群远离，说明分类效果好；如果a远大于b，说明此点与自身族群距离太远，而离其他族群近，说明分类效果差。
轮廓系数的值是介于 [-1,1] 
+ 最终计算出所有的样本点的轮廓系数平均值
+ 一般能到0.1 效果就可以了，很少能超过0.7</p>
<h3 id="api_9">评估api<a class="headerlink" href="#api_9" title="Permanent link"></a></h3>
<p>sklearn.metrics.silhouette_score(X, labels)
    计算所有样本的<strong>平均</strong>轮廓系数
    X：特征值(原始数据集)
    labels：被聚类标记的目标值（即得到的分类，通过km.labels_得到）</p>
<h2 id="kmeans">Kmeans总结<a class="headerlink" href="#kmeans" title="Permanent link"></a></h2>
<p>特点分析：
    采用迭代式算法，直观易懂并且非常实用</p>
<p>缺点：
K值难确定，k个初始值的选择对结果影响也很大，初始值选择不当，可能出现迭代多少次都无法分开，测试网址见：<a href="https://www.naftaliharris.com/blog/visualizing-k-means-clustering/">https://www.naftaliharris.com/blog/visualizing-k-means-clustering/</a>
复杂度与样本呈线性关系，时间复杂度高，因为要计算欧式距离
很难发现任意形状的簇，如环状簇，缠绕簇
<img alt="k-means无法区别" src="https://img-blog.csdnimg.cn/2018112615483990.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hZRVND,size_16,color_FFFFFF,t_70" /></p>
<h1 id="dbscan">DBSCAN算法<a class="headerlink" href="#dbscan" title="Permanent link"></a></h1>
<p>建议直接使用此方法去做聚类，效果大部分时候是要优于kmeans的</p>
<h2 id="density-based-spatial-clustering-of-applications-with-noise">基本概念 Density-Based Spatial Clustering of Applications with Noise<a class="headerlink" href="#density-based-spatial-clustering-of-applications-with-noise" title="Permanent link"></a></h2>
<p>解释：基于密度的聚类算法
<strong>核心对象</strong>：若某个点的密度达到算法设定的阈值,则其为核心点。（即 r 邻域内点的数量不小于 minPts，那么这个点就是核心点）minPts是自行设置的阈值。以某个点为圆心，r为半径，画圆，圆内包含的点数大于阈值，这个点就是核心点
<strong>ϵ-邻域的距离阈值</strong>：设定的半径r
<strong>直接密度可达</strong>：若某点p在点q的 r 邻域内，且q是核心点,则p-q直接密度可达。
<strong>密度可达</strong>：若有一个点的序列q0、q1、…qk，对任意qi-q(i-1)是直接密度可达的，则称从q0到qk密度可达，这实际上是直接密度可达的“传播”。
<strong>密度相连</strong>：若从某核心点p出发，点q和点k都是密度可达的,则称点q和点k是密度相连的
<strong>边界点</strong>:属于某一个类的非核心点,不能发展下线了，即以此点为圆心，r为半径，画圆，得到的圆内数据点个数小于设置的阈值了，此时就是边界点了
<strong>噪声点</strong>：不属于任何一个类簇的点，从任何一个核心点出发都是密度不可达的
<img alt="概念的理解图" src="https://img-blog.csdnimg.cn/2018112620483081.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hZRVND,size_16,color_FFFFFF,t_70" /></p>
<h2 id="_86">工作流程<a class="headerlink" href="#_86" title="Permanent link"></a></h2>
<p>参数D：输入数据集
MinPts：密度阈值
参数ϵ：指定半径
<img alt="流程图" src="https://img-blog.csdnimg.cn/20181126210753504.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hZRVND,size_16,color_FFFFFF,t_70" /></p>
<h2 id="_87">参数选择<a class="headerlink" href="#_87" title="Permanent link"></a></h2>
<p>半径ϵ，可以根据K距离来设定：找突变点
K距离：给定数据集P={p(i); i=0,1,…n}，计算点P(i)到集合D的子集S中所有点之间的距离，距离按照从小到大的顺序排序，d(k)就被称为k-距离。
多数时候并不会去找突变点，因为找起来困难，找的也不一定准，还是使用多个半径来测试一下为准</p>
<p>MinPts： 阈值，k-距离中k的值，一般取的小一些，多次尝试</p>
<h2 id="_88">评价<a class="headerlink" href="#_88" title="Permanent link"></a></h2>
<p><strong>优势</strong>：
不需要指定簇个数
擅长找到离群点（检测任务）
可以发现任意形状的簇
两个参数就够了</p>
<p><strong>劣势</strong>：
高维数据有些困难（可以做降维）
参数难以选择（参数对结果的影响非常大）
Sklearn中效率很慢（数据削减策略）</p>
<p><img alt="举例图" src="https://img-blog.csdnimg.cn/20181126211350569.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hZRVND,size_16,color_FFFFFF,t_70" /></p>
<h2 id="_89">直观理解两种聚类算法的网站<a class="headerlink" href="#_89" title="Permanent link"></a></h2>
<p><a href="https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/">https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/</a>
<a href="https://www.naftaliharris.com/blog/visualizing-k-means-clustering/">https://www.naftaliharris.com/blog/visualizing-k-means-clustering/</a></p>
<h1 id="_90">模型的保存与加载<a class="headerlink" href="#_90" title="Permanent link"></a></h1>
<p><code>from sklearn.externals import joblib</code>
保存模型到本地，lr是估计器，再fit之后调用即可保存
<code>joblib.dump(lr, "./tmp/test.pkl")</code></p>
<p>加载模型
<code>joblib.load("./tmp/test.pkl")</code>即可</p>
<h1 id="_91">观察算法是否过拟合或欠拟合的方式<a class="headerlink" href="#_91" title="Permanent link"></a></h1>
<p>上述说过对比在训练集上的效果和测试集的效果即可，如果训练集和测试集均较差，则欠拟合，如果在训练集表现大大优于测试集，说明过拟合了（模型复杂度高，考虑的特征多），但是没有明确说明如何看训练集的效果。
在书上看到的，直接就是estimator.score(x_train,y_train) ，在fit之后执行的。针对分类和回归，做如下思考：
1、分类：以knn为例，如果是测试集，那么他是与训练集的数据一个个求差值平方得出结果，都是以一个单独的样本来计算，那么训练集同样可以将其中每个样本与训练集所有数据进行knn计算，划分分类，同样不是一定就能预测准确的。如，在散点图上，一个训练集的异常点落在了另一个群体中，在真实情况下，他的分类是正确的，可是使用knn后，他周围的全是其它类型，那么预测时，就会将其类别划分错误
2、回归：回归的算法，经过fit之后，会得出特征对应的权重值，直观表现在二维上就是对所有散点的拟合曲线，此时将训练集代入计算得到的值，应该也不会等于真实值，也是有误差的，因此可以用来判断训练集的效果。</p>
<p>sunlime设置后，通过ctrl+b可以直接生成对应的html文档</p></article></body></html>